Tengo la siguiente imagen (coloqué una captura de pantalla de la imagen ya que su tamaño es de más de 2 MB; el original se puede descargar desde https://drive.google.com/file/d/1rC2QQBzMhZ8AG5Lp5PyrpkOxwlyP9QaE/view?usp= intercambio
Estoy leyendo la imagen usando la clase BitmapDecoder y guardándola usando un codificador JPEG. Esto da como resultado la siguiente imagen que está descolorida y descolorida.
var frame = BitmapDecoder.Create(new Uri(inputFilePath, UriKind.RelativeOrAbsolute),BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None).Frames[0]; var encoder = new JpegBitmapEncoder(); encoder.Frames.Add(frame); using (var stream = File.OpenWrite(outputFilePath)) { encoder.Save(stream); } La imagen está usando el esquema de color PhotoShop RGB . Intenté configurar el perfil de color usando el siguiente código, pero esto da como resultado este error The designated BitmapEncoder does not support ColorContexts
encoder.ColorContexts = frame.ColorContexts;Actualización : la clonación de la imagen parece solucionar el problema. Pero cuando cambio el tamaño de la imagen usando el siguiente código para la transformación, el perfil de color no se conserva
Transform transform = new ScaleTransform(width / frame.Width * 96 / frame.DpiX, height / frame.Height * 96 / frame.DpiY, 0, 0); var copy = BitmapFrame.Create(frame); var resized = BitmapFrame.Create(new TransformedBitmap(copy, transform)); encoder.Frames.Add(resized); using (var stream = File.OpenWrite(outputFilePath)) { encoder.Save(stream); }Los bits de imagen son idénticos. Este es un problema de metadatos. Este archivo de imagen contiene muchos metadatos (Xmp, Adobe, desconocido, etc.) y estos metadatos contienen dos perfiles/espacios/contextos de color :
El problema ocurre porque el orden de los dos contextos puede diferir en el archivo de destino por algún motivo. Un visor de imágenes puede no usar ningún perfil de color (Paint, Pain3D, Paint.NET, IrfanView, etc.) o usar (según mi experiencia) el último perfil de color del archivo (Windows Photo Viewer, Photoshop, etc.).
Puede solucionar su problema si clona el marco, es decir:
var frame = BitmapDecoder.Create(new Uri(inputFilePath, UriKind.RelativeOrAbsolute),BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None).Frames[0]; var encoder = new JpegBitmapEncoder(); var copy = BitmapFrame.Create(frame); encoder.Frames.Add(copy); using (var stream = File.OpenWrite(outputFilePath)) { encoder.Save(stream); }Como en este caso, el pedido se conserva tal cual.
Si recrea el marco o lo transforma de alguna manera, puede copiar los metadatos y los contextos de color de esta manera:
var ctxs = new List<ColorContext>(); ctxs.Add(frame.ColorContexts[1]); // or just remove this ctxs.Add(frame.ColorContexts[0]); // first color profile is ProPhoto RG, make sure it's last var resized = BitmapFrame.Create(new TransformedBitmap(frame, transform), frame.Thumbnail, (BitmapMetadata)frame.Metadata, ctxs.AsReadOnly()); var encoder = new JpegBitmapEncoder(); encoder.Frames.Add(resized); using (var stream = File.OpenWrite("resized.jpg")) { encoder.Save(stream); }Tenga en cuenta que una imagen que tiene más de un contexto de color es dolorosa (y en mi humilde opinión no se debe crear/guardar). Los perfiles de color están allí para garantizar una visualización correcta, por lo que dos o más perfiles (¡bastante contradictorios! sRGB vs ProPhoto) asociados con una imagen significa que se puede mostrar... de dos o más formas.
Tendrás que determinar cuál es tu perfil de color preferido en este extraño caso.