2
votes

Since last week I try to use the Windows Color System for my color conversion. By the conversion from CMYK to RGB i get the correct values:

    // Example CMYK - VALUES with 0
    float[] cmykValues = new float[4];
    cmykValues[0] = 0f / 255f;
    cmykValues[1] = 0f / 255f;
    cmykValues[2] = 0f / 255f;
    cmykValues[3] = 0f / 255f;

    System.Windows.Media.Color color = Color.FromValues(cmykValues, new Uri(@"ISOcoated_v2_300_eci.icc"));
    System.Drawing.Color rgbColor = System.Drawing.Color.FromArgb(color.R, color.G, color.B);

When I try to convert the RGB Values to Lab Values, then I get a incorrect Lab - Result:

[StructLayout(LayoutKind.Sequential)]
public struct RGBColor
{
    public ushort red;
    public ushort green;
    public ushort blue;
    public ushort pad;
};

[StructLayout(LayoutKind.Sequential)]
public struct LABColor
{
    public ushort L;
    public ushort a;
    public ushort b;
    public ushort pad;
};

 StringBuilder profileName = new StringBuilder(256);
 uint size = (uint)profileName.Capacity * 2;
 success = GetStandardColorSpaceProfile(0, LogicalColorSpace.sRGB, profileName, ref size);

 ProfileFilename sRGBFilename = new ProfileFilename(profileName.ToString());
 IntPtr hSRGBProfile = OpenColorProfile(sRGBFilename, ProfileRead, FileShare.Read, CreateDisposition.OpenExisting);

 ProfileFilename isoCoatedFilename = new ProfileFilename(@"ISOcoated_v2_300_eci.icc");
 IntPtr hIsoCoatedProfile = OpenColorProfile(isoCoatedFilename, ProfileRead, FileShare.Read, CreateDisposition.OpenExisting);

 IntPtr[] profiles = new IntPtr[] { hSRGBProfile, hIsoCoatedProfile };
 uint[] intents = new uint[] { IntentPerceptual };
 IntPtr transform = CreateMultiProfileTransform(profiles, 2, intents, 1, ColorTransformMode.BestMode, IndexDontCare);

 RGBColor[] rgbColors = new RGBColor[1];
 rgbColors[0] = new RGBColor();
 LABColor[] labColors = new LABColor[1];
 labColors[0] = new LABColor();

 rgbColors[0].red    = Convert.ToUInt16(rgbColor.R * 257);
 rgbColors[0].green  = Convert.ToUInt16(rgbColor.G * 257);
 rgbColors[0].blue   = Convert.ToUInt16(rgbColor.B * 257);

 success = TranslateColors(transform, rgbColors, 1, ColorType.RGB, labColors, ColorType.Lab);

 double colorL = Convert.ToDouble(labColors[0].L) / 65535;
 double colorA = Convert.ToDouble(labColors[0].a) / 65535;
 double colorB = Convert.ToDouble(labColors[0].b) / 65535;

When I convert the CMYK Value (0;0;0;0) to RGB (= 254:254;254) and the RGB Value to Lab I get the following values:

L = 0.0039978637360036373
a = 0.002777141984552145
b = 0.0030670634005218744

But the L-Value should be about 100%

1
There's just not enough information here to solve the problem. What does TranslateColors look like? What about GetStandardColorSpaceProfile? You'd be much better off asking a generic question about converting CMYK to LAB. - Richard J. Ross III
I have edited your title. Please see, "Should questions include “tags” in their titles?", where the consensus is "no, they should not". - John Saunders
I don't think that the color profile ISOcoated_v2_300_eci.icc works for Lab colors. It probably only supports CMYK to RGB (and vice versa) conversions. You'll probably need a specific profile for Lab colors. - Codo
@RichardJ.RossIII The TranslateColors function translates an array of colors from the source color space to the destination color space as defined by a color transform. The GetStandardColorSpaceProfile function retrieves the color profile registered for the specified standard color space. - Maxim
@Codo I have try it with different profiles. And I get always different values. Therefore I think the profiles support Lab colors. I think, that the DLL would return a error or a static 0 value. Isn't it so? Thank you for your answer! - Maxim

1 Answers

0
votes

Hm. I think you don't need to use a print profile (CMYK) when converting from color monitor's (RGB) to a device independent color model (Lab).

RGB -> XYZ -> Lab or this