在GDI +中resize时的Ghost-border(’振铃’)

会发生什么(仅在某些图像上会引人注意)是我会看到1像素的白色边框插入一个像素。 它似乎发生在光线但不是白色的区域(例如天空)。 它类似于某些东西过度锐化并且在高对比度边缘旁边可以看到鬼影边框。

这是完美再现它的repro代码。 我正在使用所有最高质量的设置进行缩放。

ImageCodecInfo encoder = null; EncoderParameters encoderParams = null; foreach (ImageCodecInfo codec in ImageCodecInfo.GetImageEncoders()) { if (codec.MimeType == "image/jpeg") { encoder = codec; // use highest quality compression settings encoderParams = new EncoderParameters(1); encoderParams.Param[0] = new EncoderParameter(Encoder.Quality, 100L); break; } } using (Bitmap input = (Bitmap)Bitmap.FromFile(inputPath, true)) { // shrink by multiple of 2 Rectangle rect = new Rectangle(0, 0, input.Width/32, input.Height/32); using (Bitmap output = new Bitmap(rect.Width, rect.Height)) { using (Graphics g = Graphics.FromImage(output)) { // use highest quality settings (updated per Mark Ransom's answer) g.CompositingMode = CompositingMode.SourceCopy; g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.PixelOffsetMode = PixelOffsetMode.HighQuality; g.SmoothingMode = SmoothingMode.HighQuality; g.DrawImage(input, rect); } output.Save(outputPath, encoder, encoderParams); } } 

有任何想法吗? 我完全不知所措。 我已经阅读了大量的问题/答案,但似乎没有一个问题影响我的情况。


编辑

这是图像之前的一个例子: http : //img14.imageshack.us/img14/4174/mg1647.jpg

这是一个图像的例子: http : //img64.imageshack.us/img64/3156/afterringing.jpg

原始文件(在托管服务“优化”它们之前)更为明显,但你可以在天空中看到较小图像上的一个像素的较亮波段。

我终于找到了一篇谈论这个问题的文章。

Libor Tinka在继续展示他的广泛filter之前随便提到了这一点,这些filter的性能优于GDI +缩放:

根据他的建议,听起来它完全符合我们的怀疑:它正在从图像边缘以外的周围像素中提取平均细节。 这对我来说似乎是算法中的一个缺陷,但这是有争议的。 要解决这个问题,有一个ImageAttributes类,您可以在其中指定超出的像素只是其中像素的镜像。 设置此似乎完全消除了振铃:

 using (ImageAttributes wrapMode = new ImageAttributes()) { wrapMode.SetWrapMode(WrapMode.TileFlipXY); g.DrawImage(input, rect, 0, 0, input.Width, input.Height, GraphicsUnit.Pixel, wrapMode); } 

非常感谢Libor Tinka提供的解决方案,以及Mark Ransom帮助我思考这个问题并给予我“振铃”一词,这使得Libor Tinka的解决方案甚至出现在我的搜索中。

尝试:

 g.CompositingMode = CompositingMode.SourceCopy; 

从我在这里的答案,纠正语法。

resize会在边界周围创建部分透明度。 设置SourceCopy告诉它用完全不透明的像素替换部分透明的像素。