Ensuring image quality when resizing in .NET

I needed to create a web page where users can upload photos. In turn, these photos will be resized into three different dimensions (small, medium, and large) and displayed on the site. The original code I was using to resize the images was pretty much hit or miss. Often times the resulting image was blurry and/or pixelated. The original code took the file from the file upload control and saved it as a bitmap. Then it used the GetThumbnailImage method to resize the image. Here is a sample.

System.Drawing.Image.GetThumbnailImageAbort myCallBack = new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallBack);
System.Drawing.Bitmap bitmap = new Bitmap(fileUpload.InputStream);
System.Drawing.Image newImage = bitmap.GetThumbnailImage(600, 800, myCallBack, IntPtr.Zero);
newImage.Save(“c:\resizedImage.jpg”);
newImage.Dispose();

private static bool ThumbnailCallback()
{
return false;
}

The callback method is called if the resize fails but I’m not sure what the IntPtr.Zero does. VS’s intellisense states “Must be System.IntPtr.Zero”, so who am I to argue. The code is very simple but not very effective. Today I found a better method. This time using an Image object instead and resizing it with the Graphics class. Finally, I use the Bitmap object to save the image.

System.Drawing.Image image = Bitmap.FromStream(file.InputStream);
System.Drawing.Imaging.ImageFormat imageFormat = image.RawFormat;
Size size = new Size(600, 800);
bitmap = new Bitmap(image, size.Width, size.Height);

Graphics resizer;
resizer = Graphics.FromImage(bitmap);
resizer.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
resizer.DrawImage(image, 0, 0, size.Width, size.Height);

bitmap.Save(“c:\resizedImage.jpg”, imageFormat);
bitmap.Dispose();
image.Dispose();

There are a few important key elements here. First is the InterpolationMode. HighQualityBicubic gives you the best quality but I find HighQualityBilinear decreases the size by at least a few KB and I couldn’t tell the difference between the two just by looking at it. Also, when using bitmap.Save(), the image format parameter is not required but it makes all the difference. For example, I resized a 2112 x 2816 pixel to 600 x 800. If I didn’t specify the image format the size was reduced from 2.2 MB to 1.1 MB. When I did specify the image format, the resulting file size was 58 KB! Again, I could barely tell the difference between the two resulting images. And finally, always clean up after yourself. Dispose of objects you no longer need, especially if they deal with streams.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s