Ghost-borders (‘sonando’) al redimensionar en GDI +

Lo que sucede (solo se nota en ciertas imágenes) es que veré un borde blanco de 1 píxel que se inserta un píxel. Parece suceder en áreas que son claras pero no blancas (por ejemplo, el cielo). Es similar a cuando algo está sobreajustado y se puede ver un borde fantasma al lado de bordes de alto contraste.

Aquí está el código repro que lo reproduce perfectamente. Estoy usando todos los ajustes de mayor calidad para escalar.

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); } } 

¿Algunas ideas? Estoy completamente desconcertado. He leído un montón de preguntas / respuestas y ninguna de ellas parece afectar mi situación.


Editar :

Este es un ejemplo antes de la imagen: http://img14.imageshack.us/img14/4174/mg1647.jpg

Este es un ejemplo después de la imagen: http://img64.imageshack.us/img64/3156/afterringing.jpg

Es más pronunciado con los archivos originales (antes de que el servicio de alojamiento los “optimice”), pero se puede ver en el cielo una banda más clara de un píxel en la imagen más pequeña.

Finalmente encontré un artículo que habla sobre esto.

Libor Tinka menciona casualmente esto antes de pasar a mostrar su amplio conjunto de filtros que supera el escalamiento de GDI +:

Según su consejo, parece que está haciendo exactamente lo que sospechábamos: está sacando detalles del promedio de los píxeles circundantes más allá del borde de la imagen. Esto me parece una falla en el algoritmo, pero eso está abierto a debate. Para resolver esto, hay una clase de ImageAttributes donde puedes especificar que los píxeles más allá son simplemente imágenes reflejas de los píxeles dentro. Establecer esto parece eliminar por completo el timbre:

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

Enorme agradecimiento tanto a Libor Tinka por la solución, como a Mark Ransom por ayudarme a pensar en esto y por darme el término “timbre”, que fue lo que hizo que la solución de Libor Tinka apareciera incluso en mis búsquedas.

Tratar:

 g.CompositingMode = CompositingMode.SourceCopy; 

De mi respuesta aquí , corregida por la syntax.

El redimensionamiento está creando una transparencia parcial alrededor de la frontera. La configuración de SourceCopy le dice que reemplace ese píxel parcialmente transparente por uno completamente opaco.