Scott Hanselman

Scaling/Resizing/Resampling an Image in ASP.NET

June 09, 2004 Comment on this post [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
Hosting By
Hosted in an Azure App Service
June 09, 2004 21:43
Funny - I am on the verge of checking out image scaling. Any tips or good sites to get started at???
June 09, 2004 23:44
Perfect - saved me a bunch of time, thanks again Scott.
June 10, 2004 0:51
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
June 10, 2004 1:07
And it's not pixel-y? (as in my example, which I'm trying to avoid)
June 10, 2004 1:21
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.
Ben
June 10, 2004 1:34
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.
June 10, 2004 3:47
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.
June 11, 2004 15:11
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
June 17, 2004 22:35
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.
June 03, 2005 16:24
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.