2

I have the following image (have put a screen-grab of the image as its size is more than 2 MB - the original can be downloaded from https://drive.google.com/file/d/1rC2QQBzMhZ8AG5Lp5PyrpkOxwlyP9QaE/view?usp=sharing

enter image description here

I'm reading the image using the BitmapDecoder class and saving it using a JPEG Encoder. This results in the following image which is off color and faded.

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

enter image description here

The image is using PhotoShop RGB Color scheme.I tried setting the color profile using the following code,but this results in this error The designated BitmapEncoder does not support ColorContexts

encoder.ColorContexts = frame.ColorContexts;

Update: Cloning the image seems to fix the issue. But when i resize the image using the following code for transformation the color profile is not preserved

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);
     }
techno
  • 6,100
  • 16
  • 86
  • 192

1 Answers1

2

The image bits are identical. This is a metadata issue. This image file contains lots of metadata (Xmp, Adobe, unknown, etc.) and this metadata contains two color profiles/spaces/contexts:

  1. ProPhoto RG (usually found in C:\WINDOWS\system32\spool\drivers\color\ProPhoto.icm)
  2. sRGB IEC61966-2.1 (usually found in WINDOWS\system32\spool\drivers\color\sRGB Color Space Profile.icm)

The problem occurs because the two contexts order may differ in the target file for some reason. An image viewer can either use no color profile (Paint, Pain3D, Paint.NET, IrfanView, etc.), or use (from my experience) the last color profile in the file (Windows Photo Viewer, Photoshop, etc.).

You can fix your issue if you clone the frame, ie:

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

As in this case, the order is preserved as is.

If you recreate the frame or transform it in any way, you can copy the metadata and color contexts like this:

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

Note an image that has more than one color context is painful (and IMHO should not be created / saved). Color profiles are for there to ensure a correct display, so two or more (rather conflicting! sRGB vs ProPhoto) profiles associated with one image means it can be displayed ... in two or more ways.

You'll have to determine what's you're preferred color profile in this strange case.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Simon Mourier
  • 132,049
  • 21
  • 248
  • 298
  • Thanks.This works,but when applying transfomation , how to preserve the color scheme.The color scheme is not saved.Please see https://stackoverflow.com/a/60112084/848968 – techno Dec 04 '21 at 14:07
  • Can you advice on how to keep the color profile while transforming? – techno Dec 04 '21 at 15:22
  • Post your failing code. – Simon Mourier Dec 04 '21 at 15:32
  • I have updated the question with the code.Please take a look – techno Dec 04 '21 at 15:42
  • Thanks a lot ... let me try it out . – techno Dec 06 '21 at 17:29
  • Another interesting thing i noted is that - when you create the `Bitmap` object of the same image using `System.Drawing` , if you supply true for `useEmbeddedColorManagement=true` the image appears like the first image which i have posted.If you do not supply this argument, it appears like the second image. I think GDI+ also gives preference to some color profile,which BitmapDecoder does not. Ref https://learn.microsoft.com/en-us/dotnet/api/system.drawing.image.fromfile?redirectedfrom=MSDN&view=dotnet-plat-ext-6.0#System_Drawing_Image_FromFile_System_String_System_Boolean_ – techno Dec 06 '21 at 17:54
  • Is there any way i can replicate the same behavior with `BitmapDecoder`? Will reversing the order of Color Profiles work? – techno Dec 06 '21 at 17:57
  • I don't think you can always assume that, you should try. Two color profiles for display like that is a nonsense as the file will never display the same on all applications. You can detect the profiles and decide what's best with some custom logic. – Simon Mourier Dec 06 '21 at 22:17
  • I noticed that when i use the `frame.thumbnail`(original image thumbnail) to create the new `BitmapFrame` , the resulting image with exif orientation tag will have wrong orientation thumbnail image as the metadata is stripped off – techno Feb 17 '22 at 07:54
  • `var resized = BitmapFrame.Create(new TransformedBitmap(frame, transform),null,null, frame.ColorContexts?.Reverse().ToList().AsReadOnly());` This fixes the wrong orientation of the thumbnail but the thumbnail image does not have the correct color profile. – techno Feb 17 '22 at 07:55
  • @techno - you should ask another question – Simon Mourier Feb 17 '22 at 08:00
  • Thanks for replying.. I will create a new question shortly. – techno Feb 17 '22 at 08:01
  • I have posted the new question here https://stackoverflow.com/questions/71154476/windows-media-imaging-generating-correct-thubnail-for-image-with-multiple-color – techno Feb 17 '22 at 08:14