Scaling/Resizing/Resampling an Image in ASP.NET
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.
About Newsletter
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
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.
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.
Here's my post about it:
http://thomasfreudenberg.com/blog/archive/2003/09/03/156.aspx
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.
Comments are closed.