c# - tamaño - Bordes fantasmas(''timbre'') al redimensionar en GDI+
guardar imagen en carpeta c# (2)
Finalmente encontré un artículo que habla de esto.
Libor Tinka menciona esto ocasionalmente antes de mostrar su extenso conjunto de filtros que superan en gran medida el escalado de GDI +:
Según su consejo, parece que está haciendo exactamente lo que sospechábamos: está sacando el promedio de los detalles de los píxeles que rodean más allá del borde de la imagen. Esto me parece un defecto en el algoritmo, pero está abierto a debate. Para resolver esto, hay una clase ImageAttributes en la que puede especificar que los píxeles que se encuentran más allá son simplemente imágenes reflejadas de los píxeles que contiene. Configurando esto parece eliminar completamente el timbre:
using (ImageAttributes wrapMode = new ImageAttributes())
{
wrapMode.SetWrapMode(WrapMode.TileFlipXY);
g.DrawImage(input, rect, 0, 0, input.Width, input.Height, GraphicsUnit.Pixel, wrapMode);
}
Muchísimas gracias a Libor Tinka por la solución, ya 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 en mis búsquedas.
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 que ocurre en áreas que son claras pero no blancas (por ejemplo, el cielo). Es similar a cuando algo está demasiado afilado y se puede ver un borde fantasma junto a los bordes de alto contraste.
Aquí está el código de reproducción que lo reproduce perfectamente. Estoy usando todos los ajustes de calidad más altos 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 de imagen anterior : 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 puede ver en el cielo una banda más clara de un píxel en la imagen más pequeña.
Tratar:
g.CompositingMode = CompositingMode.SourceCopy;
De mi respuesta here , corregida por la sintaxis.
El cambio de tamaño está creando una transparencia parcial alrededor de la frontera. La configuración de SourceCopy
le indica que reemplace ese píxel parcialmente transparente por uno completamente opaco.