如何禁用.NET / GDI +的子采样?

我想使用Bitmap类保存JPEG图像。 我注意到,无论我指定的质量水平如何,锋利的边缘总是blury。 我发现这是由于一个或多个通道的子采样。 保存图像时如何禁用子采样?

我目前正在使用此代码:

EncoderParameters parameters = new EncoderParameters(1); parameters.Param[0] = new EncoderParameter(Encoder.Quality, 85L); ImageCodecInfo codec = GetEncoderInfo("image/jpeg"); image.Save(path, codec, parameters); 

注意

我知道JPEG是有损的,但这不是问题。 如果我使用ImageMagick并使用默认选项保存图像,我会得到类似的结果。 但是,如果我指定1:1:1子采样,则模糊消失。

我不想使用PNG,因为我需要更好的压缩。 如果我将图像保存为BMP,然后手动将其转换为JPEG,我会得到很好的结果,而不会模糊。 因此,格式不是这里的问题。

JPEG是使用有损压缩的图像格式。 无论您选择何种质量设置,都会导致图像降级。

尝试使用更好的格式,例如.PNG。 由于.PNG文件使用无损压缩算法,因此您将无法获得所看到的工件。


问题(在阅读您的编辑之后)可能是由于GDI +在其默认编码器中对JPG文件使用4:1:1子采样。

我相信你可以安装另一个编码器(不知道如何做到这一点)。 否则,我建议使用像MagickNet这样的东西来处理保存你的JPG文件。 (它是ImageMagick的.net包装器 – 其中有几个。)


编辑2:进一步研究之后,通过调整编码器亮度表和色度表 ,看起来你可能会对此产生一些影响。

我一直想弄清楚如何做2天,我只是想到M $不会在GDI +中包含这么简单的function。 作为替代方案,我通过在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 +中禁用子采样,我仍然希望听到它…

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