Quality of Dynamic Images

Published 12 January 04 10:24 AM | despos

Got this question from a comment to a previous post.

Any idea how to control the quality of a generated JPEG image from the DynamicImage control?

More in general the question can be generalized to "how to control the quality of a generated JPEG image in .NET".

As far as I know today, DynamicImage generates JPEG images only in one case--if your source image is, say, GIF and you want to output a JPEG. Or if you're attempting to send an image to a device that doesn't accept it but does accept JPEGs.

Looking at the current implementation of the DynamicImage control in ASP.NET 2.0, it normalizes any input image (bytes, GDI+ object, URL)  to a GDI+ object and then uses the Bitmap.Save method to output the image to a particular type--PNG, JPG, GIF, BMP and so forth. This technique can be used from within your own ASIX handlers or in ASP.NET 1.x handlers that return dynamic images. (I'm just finishing a MSDNMag article about dynamic images in ASP.NET 1.x)

I wouldn't say that the default quality of JPG is bad (based on my limited experience) but I understand that it is a personal factor, often app-specific. Finally, I could just be wrong. I remember that all colleagues were telling me (years ago) that my feeling with image quality wasn't that great...

To come to the point, you can control the compression ratio of JPEGs. I agree that the default ratio is probably OK for Web images but not necessarily for a high-quality image.

// Set the quality to 40 (must be a long)
Encoder qualityEncoder = Encoder.Quality;
EncoderParameter ratio = new EncoderParameter(qualityEncoder, 40L);

// Add the quality parameter to the list
codecParams = new EncoderParameters(1);
codecParams.Param[0] = ratio;

// Save to JPG
bmp.Save(fileName, jpegCodecInfo, codecParams);

The first step is to get the ImageCodecInfo structure for the JPEG image. The GDI+ interface provides no direct method to get this object. You must resort to a little trick—enumerate all the image encoders and check their MIME type properties against the JPEG MIME type string (image/jpeg). The ImageCodecInfo structure contains information inherent in the encoding and decoding of the image. The code is an excerpt from this MSDN article.

 

Comments

# Sigurdur G. Gunnarsson said on January 12, 2004 05:42 AM:

It's a fact, the JPG codec that .NET uses is NOT good. I've done quite a bit of testing with this, including setting the quality like you mentioned, but even if I set it WAY high it won't even compare to 50% quality in Photoshop's JPG codec.

Or could this be a bug?

# Kevin Daly said on January 12, 2004 07:12 AM:

I've used this method to manipulate jpeg quality in the past with .NET (most significantly in an image manipulation program, where both resolution and quality were adjustable with sliders),and it's always worked fine for me.
So far however I'm not having any luck doing it with a .asix file (I'm overriding CreateImage, saving to a MemoryStream and reloading the image from there)... I get the same result regardless of specified quality, and the effect is very noticeable (if you want to see crappy jpeg quality, green text on a grey background is always fun).
Tomorrow I'm going to dredge through all my old bits of code to see if I've missed something.

# DinoE said on January 12, 2004 10:33 AM:

>>So far however I'm not having any luck doing it with a .asix file (I'm overriding
>>CreateImage, saving to a MemoryStream and reloading the image from there)...
>>I get the same result regardless of specified quality, and the effect is very
>>noticeable (if you want to see crappy jpeg quality, green text on a grey
>>background is always fun). Tomorrow I'm going to dredge through all my old bits
>>of code to see if I've missed something.

This can be anyway due to a bug in the alpha, though. I have no problem instead buying the statement the .NET JPEG codec is ... not that great. So to speak.

# Kevin Daly said on January 13, 2004 03:02 AM:

Well, after doing a lot of tests I've found that Whidbey is actually consistent with the behaviour in 1.1...where I was getting results was because I was using a completely dynamically generated image. It appears that if the original source of the image is an existing image, the quality settings have about the effect you would expect (which is what I observed with my image processing app). If however the image is generated from scratch, any setting other than a very high one yields pretty horrible results (and it's never all that great).
Strange, but true.
Anyway, if I need to create an image from scratch I can probably live with PNG (which is excellent).

# TrackBack said on January 19, 2004 09:57 PM:

Leave a Comment

(required) 
(required) 
(optional)
(required)