Optimising Image Quality In System.Drawing
Sometimes optimising images to have an adequate image to file size ratio can be difficult when dynamically generating images using “System.Drawing”.
Over the years, I have worked on quite a few different projects around the use of “System.Drawing” and recently I found a flexible way of being able to have control over the image quality and file size.
Here’s a snippet of of code from my Generic Handler (.ashx) file:
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "image/jpeg";
//Create a new Bitmap
Bitmap oBitmap = new Bitmap(800, 800, PixelFormat.Format24bppRgb);
//Load Background Graphic from Image
Graphics oGraphics = Graphics.FromImage(oBitmap);
#region Your Image Code
//Insert your code here.
#endregion
#region Stage 1: Image Quality Options
oGraphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
oGraphics.SmoothingMode = SmoothingMode.HighQuality;
oGraphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
oGraphics.CompositingQuality = CompositingQuality.HighQuality;
#endregion
//Clear graphic resources
oGraphics.Dispose();
#region Stage 2: Image Quality Options
//Output image
ImageCodecInfo[] Info = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();
EncoderParameters Params = new System.Drawing.Imaging.EncoderParameters(1);
Params.Param[0] = new EncoderParameter(Encoder.Quality, 100L); //Set image quality
context.Response.ContentType = Info[1].MimeType;
oBitmap.Save(context.Response.OutputStream, Info[1], Params);
#endregion
}
System.Drawing.Graphics Optimisations
In all my “System.Drawing” development projects, I’ve always set the graphic object quality options (lines 19-22) and found that it never really worked for me. The reason for this is because I always placed these settings after creating my System.Drawing.Graphics object prior to my custom code. So the image was getting optimised before any of my functionality had taken place. Rubbish!
The key is to set all your System.Drawing.Graphics object settings just before you dispose of it. Makes sense doesn’t it? Don’t know how I made such a noob mistake.
By default, .NET uses the web safe options when converting Bitmap to an image and setting those four properties will have a big affect on how your image looks.
Compression Level
This is the good bit!
.NET gives you the ability to carry out further tweaks on how your image will be rendered by allowing us to set the compression level. The compression level can be tweaked by modifying the value passed to the “EncoderParameter” constructor (line: 34).
For another example of how this can be used, take a look at the following MSDN article: http://msdn.microsoft.com/en-us/library/bb882583.aspx