Saturday, March 21, 2009

BSG Corner Clipper

To celebrate the end of BSG this weekend, and to learn how ASP.NET services work, I have written a web service that will clip off the corners of your images (JPEG or PNG) in a BSG stylie. Behold:



I've added the source code below in case you are interested. It was written very quickly, so don't expect production quality, but it illustrates how easy these services are to write:

<%@ WebHandler Language="C#" Class="Handler" %>

using System;
using System.Web;
using System.Net;
using System.Drawing;
using System.Drawing.Imaging;

public class Handler : IHttpHandler
{
ImageFormat ParseImageExtension(string src)
{
string ext = src.Substring(src.LastIndexOf('.') + 1);
if (ext == "gif")
{
return ImageFormat.Gif;
}
else if (ext == "png")
{
return ImageFormat.Png;
}
else if (ext == "jpg")
{
return ImageFormat.Jpeg;
}
else if (ext == "jpeg")
{
return ImageFormat.Jpeg;
}
return null;
}

string ImageFormat2ContentType(ImageFormat imageFormat)
{
return "image/" + imageFormat.ToString();
}

public void ProcessRequest (HttpContext context)
{
// Get the src parameter
var src = context.Request.Params["src"];

// Get the corner color (optional)
var color = context.Request.Params["color"];
if (color == null)
{
color = "White";
}
// Get the size of the corner
var corner = context.Request.Params["corner"];
int cornerSize = -1;
if (corner != null)
{
Int32.TryParse(corner, out cornerSize);
}
if (cornerSize < 1)
{
cornerSize = 20;
}

if (src != null)
{
// Extract the image type
var imageFormat = ParseImageExtension(src);
if(imageFormat != null)
{
// Request the source image
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(src);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
try
{
// Make a bitmap from the source image
using(var bitmap = Bitmap.FromStream(response.GetResponseStream()))
using(var b = new SolidBrush(Color.FromName(color)))
{
ClipCorners(bitmap, b, cornerSize);
System.IO.MemoryStream buffer = new System.IO.MemoryStream();
bitmap.Save(buffer, imageFormat);
context.Response.ContentType = ImageFormat2ContentType(imageFormat);
context.Response.BinaryWrite(buffer.ToArray());
context.Response.End();
}
}
finally
{
response.Close();
}
}
}
}

void ClipCorners(Image image, Brush b, int r)
{
using (var g = Graphics.FromImage(image))
{
g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
int w = image.Width;
int h = image.Height;
if (r >= w)
{
r = w / 10;
}
if (r >= h)
{
r = h / 10;
}
if (r > 0)
{
g.FillPolygon(b, new Point[]
{
new Point(0, 0),
new Point(0, r),
new Point(r, 0)
});
g.FillPolygon(b, new Point[]
{
new Point(w, 0),
new Point(w - r, 0),
new Point(w, r)
});
g.FillPolygon(b, new Point[]
{
new Point(0, h),
new Point(0, h - r),
new Point(r, h)
});
g.FillPolygon(b, new Point[]
{
new Point(w, h),
new Point(w, h - r),
new Point(w - r, h)
});
}
}
}

public bool IsReusable {
get {
return false;
}
}

}

No comments: