Converting Colors with Color Management

When converting an image with a profile between RGB, CMYK, or grayscale (including converting within the same color space, e.g. RGB -> RGB), you should apply color management. Without color management, the result may look non-realistic, or can even be unpredictable. To convince you of the importance of color management, let us compare the results of conversions between CMYK and RGB with and without color management.

CMYK to RGB conversion with and without color management

The image which was converted with color management has original colors, whereas converting the image without color management produces distorted colors. Let us consider how to use color management in practice.

  1. Select one of the available color management engines presented by the ColorManagementEngine enumeration. See details in the Selecting Color Management Engine topic.
  2. Specify an output profile (profile of the device where the image will be displayed, e.g. monitor or printer).
  3. Set a default CMYK profile to handle such cases when the input color profile is not automatically loaded from the image.

Color management also allows you to preview on one device how an image will be looking on an other device. This is called color proofing.

A special case of color conversion is converting from device colors to device colors, for example, from CMYK to CMYK. Such conversion can be realized using special color profile that are called device link color profiles.

Converting CMYK to RGB

In order to convert a CMYK image to RGB, you should specify the profile of the color space which you are converting to. The code snippets below use a standard sRGB profile. Also the code handles such cases when the source file does not contain an embedded profile: in this case the default CMYK profile is used; mostly the result will be better than straight color conversion.

The first snippet performs the conversion using the Bitmap.ColorManagement property:

C#
using (var bitmap = new Bitmap(@"Images\cmyk.jpg"))
{
    bitmap.ColorManagement.ColorManagementEngine = ColorManagementEngine.LittleCms;
    if (bitmap.ColorProfile == null)
        bitmap.ColorProfile = new ColorProfile(@"_Input/ColorProfiles/EuroscaleCoated.icc");
    bitmap.ColorManagement.DestinationProfile = ColorProfile.FromSrgb();
    bitmap.ColorManagement.Convert(PixelFormat.Format24bppRgb);
    bitmap.Save(@"Images\Output\out.jpg");
}

The second snippet performs the same conversion as the previous one, but it is more memory-friendly thanks to using pipeline; also, it uses the DefaultSourceProfile property to set the default CMYK profile:

C#
using (var reader = new JpegReader(@"Images\cmyk.jpg"))
using (var converter = new ColorConverter(PixelFormat.Format24bppRgb))
using (var writer = new JpegWriter(@"Images\Output\out.jpg"))
{
    converter.ColorManagementEngine = ColorManagementEngine.LittleCms;
    converter.DefaultSourceProfile = new ColorProfile(@"_Input/ColorProfiles/EuroscaleCoated.icc");
    converter.DestinationProfile = ColorProfile.FromSrgb();
    Pipeline.Run(reader + converter + writer);
}

Converting RGB to CMYK

Converting color from RGB to CMYK is almost the same. You should specify the CMYK color profile which corresponds to the printer where the image will be printed.

The following code snippets apply conversion between RGB and CMYK and use the Euroscale Coated profile.

The first snippet uses the Bitmap.ColorManagement property.

C#
using (var bitmap = new Bitmap(@"Images\in.jpg"))
{
    bitmap.ColorManagement.ColorManagementEngine = ColorManagementEngine.LittleCms;
    if (bitmap.ColorProfile == null)
        bitmap.ColorProfile = ColorProfile.FromSrgb();
    bitmap.ColorManagement.DestinationProfile = new ColorProfile(@"_Input/ColorProfiles/EuroscaleCoated.icc");
    bitmap.ColorManagement.Convert(PixelFormat.Format32bppCmyk);
    bitmap.Save(@"Images\Output\out.jpg");
}

The second snippet performs the same conversion as the previous one, but it is more memory-friendly thanks to using pipeline; also, it uses the DefaultSourceProfile property to set the default CMYK profile:

C#
using (var reader = new JpegReader(@"Images\in.jpg"))
using (var converter = new ColorConverter(PixelFormat.Format32bppCmyk))
using (var writer = new JpegWriter(@"Images\Output\out.jpg"))
{
    converter.ColorManagementEngine = ColorManagementEngine.LittleCms;
    converter.DefaultSourceProfile = ColorProfile.FromSrgb();
    converter.DestinationProfile = new ColorProfile(@"_Input/ColorProfiles/EuroscaleCoated.icc");
    Pipeline.Run(reader + converter + writer);
}

Color Proofing

To preview how an image is looking on a device after being displayed on another device, you can use the ColorConverter.TargetDeviceProfile property. For example, this feature could be helpful if you want to display on a screen how the image is looking after being printed by a specific printer. In this case you use monitor's profile as DestinationProfile and the printer's profile as TargetDeviceProfile.

The following snippet demonstrates the idea. Here, we preview an image on the screen, so we get the profile associated with the monitor using the ColorProfile.FromScreen() method, and as the target we use a color profile from the FOGRA39 data set (it represents colors of a typical output from a commercial offset printing). The conversion is memory-friendly, thanks to using pipeline:

C#
using (var reader = ImageReader.Create(@"Images\Copenhagen_RGB.jpg"))
using (var converter = new ColorConverter())
using (var writer = ImageWriter.Create(@"Images\Output\out.jpg"))
{
    converter.DestinationPixelFormat = PixelFormat.Format24bppRgb;
    converter.DefaultSourceProfile = ColorProfile.FromSrgb();
    converter.TargetDeviceProfile = new ColorProfile(@"_Input/ColorProfiles/ISOcoated_v2_eci.icc");
    converter.DestinationProfile = ColorProfile.FromScreen();
    converter.TransformationIntent = ColorTransformationIntent.Perceptual;

    Pipeline.Run(reader + converter + writer);
}

Using Device Link Color Profiles

Device link profiles are able to convert directly from device colors to device colors. They are essential to certain conversions and effects. To perform a color conversion using a device link profile, set the profile via the ColorConverter.DeviceLinkProfile property. It requires only one device link profile to perform a conversion, but such profiles cannot be embedded into images. So, you may use ColorConverter.DestinationProfile to set a color profile that should be embedded into the result image.

The following snippet performs the CMYK to CMYK color conversion using an ISO Coated v2 to PSO Coated v3 device link profile:

C#
using (var reader = ImageReader.Create(@"Images\tangerine.tif"))
using (var converter = new ColorConverter(PixelFormat.Format32bppCmyk))
using (var writer = ImageWriter.Create(@"Images\Output\DeviceLinkProfileTest.tif"))
{
    converter.ColorManagementEngine = ColorManagementEngine.LittleCms;
    converter.DeviceLinkProfile = new ColorProfile(@"_Input\ColorProfiles\ISOcoated_v2_to_PSOcoated_v3_DeviceLink.icc");
    converter.DestinationProfile = new ColorProfile(@"_Input\ColorProfiles\PSOcoated_v3.icc");

    Pipeline.Run(reader + converter + writer);
}

See Also

Manual

Reference