How to disable subsampling using .NET / GDI +?

I am trying to save a JPEG image using the Bitmap class. I noticed that sharp edges always blur, regardless of the quality level that I specify. I realized that this is due to a subsample of one or more channels. How to disable subsampling while saving 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 lost, but that is not a problem. If I use ImageMagick and save the image with the default settings, I get similar results. However, if I set a 1: 1: 1 subselect, the blur 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 great results without blurring. Therefore, the format here is not a problem.

+4
source share
3 answers

JPEG is an image format in which lossy compression is used . This will degrade your image, no matter what quality setting you choose.

Try using the best format for this, for example .PNG. Since .PNG files use a lossless compression algorithm, you will not get the artifacts that you see.


The problem (after reading your changes) is probably due to the fact that GDI + uses 4: 1: 1 downsampling for JPG files in Encoder by default.

I believe that you can install another encoder (do not know how to do this). Otherwise, I would recommend using something like MagickNet to process your JPG files. (This is the .net shell for ImageMagick - there are a couple of them).


Edit 2: After further studying this, it looks like you can have some effect on this by changing the Encoder Luminance Table and Chrominance Table .

+4
source

I tried to figure out how to do this in 2 days, it just drives me crazy that M $ would not include such a simple function in GDI +. As an alternative, I implemented my own Bitmap -> Jpeg compressor by writing a small wrapper in libjpeg. The critical step is to turn off the subsample as follows:

 struct jpeg_compress_struct cinfo; ... jpeg_set_defaults(&cinfo); cinfo.comp_info[0].h_samp_factor = 1; cinfo.comp_info[0].v_samp_factor = 1; cinfo.comp_info[1].h_samp_factor = 1; cinfo.comp_info[1].v_samp_factor = 1; cinfo.comp_info[2].h_samp_factor = 1; 

code>

However, another problem arose for me: libjpeg does not support writing exif tags, which I also need. Of course, GDI + will not add tags without recoding jpg, which will completely defeat the goal. I looked at libexif, but could not compile it for a visual studio. If someone had figured out a way to disable subsampling in GDI +, I would still like to hear about it ...

+2
source

Have you changed the SmoothingMode property for your Graphics object? In my experiments, I found that specifying the SmoothingMode value is something other than the default, blurring sharp edges. Try it and see if that helps.

0
source

All Articles