Scott Hanselman

Scaling/Resizing/Resampling an Image in ASP.NET

June 9, '04 Comments [10] Posted in ASP.NET | DasBlog
Sponsored By

A friend was an image in C# yesterday, and was commenting on how crappy the output looked.  His code was very similar to the code in dasBlog that resizes an image when an entry is email-to-blog'ed.

/// Copyright (c) 2003, newtelligence AG. (http://www.newtelligence.com)
/// <summary>

/// This function is used for thumbnailing and gets an image encoder
/// for a given mime type, such as image/jpeg
/// </summary>
/// <param name="mimeType"></param>
/// <returns></returns>
private ImageCodecInfo GetEncoderInfo(string mimeType)
{
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
foreach (ImageCodecInfo codec in codecs)
{
if (codec.MimeType == mimeType)
{
return codec;
}
}
return null;
}

<SNIPPET>

string absoluteFileName = Path.Combine(binariesPath, fileName);
string thumbBaseFileName = Path.GetFileNameWithoutExtension(fileName)+"-thumb.dasblog.JPG";
string thumbFileName = Path.Combine(binariesPath, thumbBaseFileName);
Bitmap sourceBmp = new Bitmap(absoluteFileName);
if ( sourceBmp.Height > siteConfig.Pop3InlinedAttachedPicturesThumbHeight )
{
Bitmap targetBmp = new Bitmap(sourceBmp,new Size(
Convert.ToInt32(Math.Round((((double)sourceBmp.Width) * (((double)siteConfig.Pop3InlinedAttachedPicturesThumbHeight) / ((double)sourceBmp.Height))),0)),
siteConfig.Pop3InlinedAttachedPicturesThumbHeight));

ImageCodecInfo codecInfo = GetEncoderInfo("image/jpeg");
Encoder encoder = Encoder.Quality;
EncoderParameters encoderParams= new EncoderParameters(1);
long compression=75;
EncoderParameter encoderParam = new EncoderParameter(encoder,compression);
encoderParams.Param[0] = encoderParam;
targetBmp.Save(thumbFileName,codecInfo,encoderParams);

string absoluteUri = new Uri( binariesBaseUri, fileName ).AbsoluteUri;
string absoluteThumbUri = new Uri( binariesBaseUri, thumbBaseFileName ).AbsoluteUri;
entry.Content += String.Format("<div class=\"inlinedMailPictureBox\"> <a href=\"{0}\"><img border=\"0\" class=\"inlinedMailPicture\" src=\"{2}\"></a> <br> <a class=\"inlinedMailPictureLink\" href=\"{0}\">{1}</a></div>",absoluteUri, fileName, absoluteThumbUri);
scalingSucceeded = true;

</SNIPPET>

This code (above) works fine for extracting an image from an email and scaling (thumbnailing) it, but the result is fairly jaggy, and one would certainly expect better resampling than is seen in the image above.

I found this article on DevEx that seemed to offer these lines as a possible solution:

    g.SmoothingMode =SmoothingMode.HighQuality;
    g.InterpolationMode =InterpolationMode.HighQualityBicubic;
    g.PixelOffsetMode =PixelOffsetMode.HighQuality;

But there doesn't appear to be any visible change (to my eye) with these added.  Should the SmoothingMode be set to 'SmoothingModeAntiAlias' instead?  Smooth resampling of an image in C# certainly seems it should be a 'solved problem.'  Perhaps I'm not Googling well.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb
Wednesday, 09 June 2004 17:43:02 UTC
Funny - I am on the verge of checking out image scaling. Any tips or good sites to get started at???
Wednesday, 09 June 2004 19:44:57 UTC
Perfect - saved me a bunch of time, thanks again Scott.
Wednesday, 09 June 2004 20:51:42 UTC
Here's how I do it:

Private Function GenerateThumbnail(ByVal img As Image, _
ByVal Height As Integer, ByVal Width As Integer) As Image
Dim imgThumb As Image = New Bitmap(Width, Height, img.PixelFormat)
Dim g As Graphics = Graphics.FromImage(imgThumb)
With g
.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
End With
Dim rect As Rectangle = New Rectangle(0, 0, Width, Height)
g.DrawImage(img, rect)
Return imgThumb
End Function
Wednesday, 09 June 2004 21:07:02 UTC
And it's not pixel-y? (as in my example, which I'm trying to avoid)
Scott Hanselman
Wednesday, 09 June 2004 21:21:25 UTC
Might also check out the code for image resizing in nGallery (http://www.ngallery.org). I know Ken did some fancy stuff in there, but the specifics elude my tired brain at the moment.
Wednesday, 09 June 2004 21:34:49 UTC
Here's a live demo:

http://www.philweber.com/image.aspx (actual size)
http://www.philweber.com/image.aspx?width=320 (resized)

Substitute different values for height and/or width to judge quality.
Wednesday, 09 June 2004 23:47:37 UTC
I had the same problem when I made a "Thumbnailer" a while back. The interpolation quality didn't seem to take effect unless I manually did the drawing rather than just letting the framework do the resizing on the new image creation. After creating a new image of the appropriate size (and Graphics object (g)) on it I used:

g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(sourceImage, new Rectangle(new Point(0,0), targetSize));

That makes very nice, jaggie-free thumbnails for me. Hope that helps.
Friday, 11 June 2004 11:11:14 UTC
I've had the same problem in .Text and solved it similar to marklio by setting g.InterpolationMode to InterpolationMode.HighQualityBicubic

Here's my post about it:

http://thomasfreudenberg.com/blog/archive/2003/09/03/156.aspx
Thursday, 17 June 2004 18:35:42 UTC
I'd like to think nGallery has pretty good scaling. In my gallery, I never notice any real obvious pixelations. Anyway, we do it in just a few short lines:

Graphics thumb;
Bitmap bitmap = new Bitmap(_width, _height);
thumb = Graphics.FromImage(bitmap);
thumb.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
thumb.DrawImage(image, 0, 0, _width, _height);

We don't change the smoothing mode or the pixel offset mode, just the interpolation mode. Perhaps they work against the interpolation mode in some way.
Friday, 03 June 2005 12:24:39 UTC
Nice and very useful tutorial. Thanks
Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.