views:

583

answers:

4

I am trying to save a JPEG image using the Bitmap class. I noticed that sharp edges were always blury regardless of the quality level that I specify. I figured out that it is due to subsampling of one or more of the channels. How do I disable subsampling when saving the image?

I am currently using this code:

EncoderParameters parameters = new EncoderParameters(1);
parameters.Param[0] = new EncoderParameter(Encoder.Quality, 85L);

ImageCodecInfo codec = GetEncoderInfo("image/jpeg");
image.Save(path, codec, parameters);

NOTE

I know that JPEG is lossy, but that's not the issue here. If I use ImageMagick and save the image with the default options, I get similar results. However, if I specify 1:1:1 subsampling, the blurring disappears.

I do not want to use PNG because I need better compression. If I save the image as BMP and then convert it manually to JPEG, I get excellent results, without blurring. Therefore, the format is not the issue here.

+2  A: 

JPEG is an image format which uses lossy compression. It will cause degredation of your image, no matter what quality setting you choose.

Try using a better format for this, such as .PNG. Since .PNG files use a lossless compression algorithm, you will not get the artifacts you are seeing.


The problem (after reading your edits) is probably due to the fact that GDI+ uses 4:1:1 subsampling for JPG files in it's default Encoder.

I believe you could either install another encoder (not sure how to do this). Otherwise, I'd recommend using something like MagickNet to handle saving your JPG files. (It's a .net wrapper for ImageMagick - there are a couple of them out there.)


Edit 2: After further looking into this, it looks like you may be able to have some effect on this by tweaking the Encoder Luminance Table and Chrominance Table.

Reed Copsey
I know that JPEG is lossy, but that's not the issue here. If I use ImageMagick and save the image with the default options, I get similar results. However, if I specify 1:1:1 subsampling, the blurring disappears.
Antoine Aubry
I couldn't find any documentation on LuminanceTable and ChrominanceTable. I also looked for MagickNet, but the web site seems to be dead :(
Antoine Aubry
@Antoine Aubry: I think the site is just down temporarily. I couldn't find much info on those, but they are related to jpeg compression and the jpeg encoder, so some searching may help. For C# usage of ImageMagick, also see: http://sourceforge.net/projects/imagemagickapp/
Reed Copsey
@reed-copsey: Do you know of any documentation on using LuminanceTable and ChrominanceTable with the built in Jpeg codec? Sadly I can't get the code at http://msdn.microsoft.com/en-us/library/bb882589.aspx to run without an overflow exception...
Oskar Austegard
A: 

There's a reference to disabling chroma subsampling in the comments of this article, but I didn't have time to look through the code.

http://www.codeproject.com/KB/GDI-plus/csharpfilters.aspx?display=PrintAll&fid=3511&df=90&mpp=25&noise=3&sort=Position&view=Quick&select=2712289

Mark Ransom
The reference is only on a comment and there is no answer to that question :(
Antoine Aubry
Sorry to be misleading. I guess they solved it by allowing save to .bmp instead of .jpg.
Mark Ransom
A: 

Did you change SmoothingMode property for your Graphics object? In my experimentation, I have found that specifying SmoothingMode value to be anything other than the default blurs the sharp edges. Try it and see if that helps.

SolutionYogi
+2  A: 
Metal450