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.

4

3 回答 3

4

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.

于 2009-04-13T22:28:26.247 回答
2

两天来我一直试图弄清楚如何做到这一点,这让我大吃一惊,M$ 不会在 GDI+ 中包含如此简单的功能。作为替代方案,我通过在 libjpeg 周围编写一个小的包装函数来实现我自己的 Bitmap -> Jpeg 压缩器。关键步骤是像这样关闭子采样:

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;

但是,这给我带来了另一个问题:libjpeg 不支持编写 exif 标签,我也需要它。当然 GDI+ 不会在不重新编码 jpg 的情况下添加标签,这完全违背了目的。我查看了 libexif,但无法在 Visual Studio 下编译。如果有人确实想出了一种方法来禁用 GDI+ 中的二次采样,我仍然很想听听……

于 2009-07-12T18:12:56.510 回答
0

您是否更改了 Graphics 对象的 SmoothingMode 属性?在我的实验中,我发现将 SmoothingMode 值指定为默认值以外的任何值都会模糊锐利的边缘。试试看是否有帮助。

于 2009-06-16T18:21:41.313 回答