Convert RGB color to CMYK?

2020-01-25 08:05发布

问题:

I'm looking for an algorithm to convert an RGB color to CMYK. Photoshop is performing the conversion below:

R = 220 G = 233 B = 174

C = 15 M = 0 Y = 40 K = 0

回答1:

The conversion from RGB to CMYK is dependent on the physical device/process being used to lay down the CMYK ink. These are represented in software as Color Profiles. ICC and ICM color profiles of physical devices determine the resulting colors.

If you are not concerned with true representation on a physical device then use the direct conversion formulas in other posts.

If, however, you are concerned with this aspect, then you need to use a either the Windows Color Management APIs or something like LittleCMS to do the color conversions for you (as they apply the proper color profile during the conversion).



回答2:

If you want good result, you need to apply a color profile. In .NET, you can do it like that (assuming the the original CMYK components are in the range between 0 and 255):

float[] colorValues = new float[4];
colorValues[0] = c / 255f;
colorValues[1] = m / 255f;
colorValues[2] = y / 255f;
colorValues[3] = k / 255f;

System.Windows.Media.Color color = Color.FromValues(colorValues,
    new Uri(@"C:\Users\me\Documents\ISOcoated_v2_300_eci.icc"));
System.Drawing.Color rgbColor = System.Drawing.Color.FromArgb(color.R, color.G, color.B);

Note that two different Color classes from two different namespaces are used. And you probably need to add the PresentationCore DLL as a reference.

The required color profile can be downloaded from the downloads section of eci.org. It's part of a bigger ZIP file containing several profiles. They explicitly recommend to use the ISO Coated v2 300% (ECI) profile.

If you need to convert a complete image from CMYK to RGB, there are special classes for this in the same namespace.



回答3:

Check out this link: http://www.codeproject.com/KB/applications/xcmyk.aspx. It gives this formula.

Black   = minimum(1-Red,1-Green,1-Blue)
Cyan    = (1-Red-Black)/(1-Black)
Magenta = (1-Green-Black)/(1-Black)
Yellow  = (1-Blue-Black)/(1-Black) 


回答4:

My complete example for C# conversion between CMYK <-> HEX:

public class ColorConverter
{
    public static string CMYKtoHex(decimal[] cmyk)
    {
        if (cmyk.Length != 4) return null;

        var r = (int)(255 * (1 - cmyk[0]) * (1 - cmyk[3]));
        var g = (int)(255 * (1 - cmyk[1]) * (1 - cmyk[3]));
        var b = (int)(255 * (1 - cmyk[2]) * (1 - cmyk[3]));

        var hex = "#" + r.ToString("X2") + g.ToString("X2") + b.ToString("X2");
        return hex;
    }

    public static decimal[] HexToCMYK(string hex)
    {
        decimal computedC = 0;
        decimal computedM = 0;
        decimal computedY = 0;
        decimal computedK = 0;

        hex = (hex[0] == '#') ? hex.Substring(1, 6) : hex;

        if (hex.Length != 6)
        {
            return null;
        }

        decimal r = int.Parse(hex.Substring(0, 2), System.Globalization.NumberStyles.HexNumber);
        decimal g = int.Parse(hex.Substring(2, 2), System.Globalization.NumberStyles.HexNumber);
        decimal b = int.Parse(hex.Substring(4, 2), System.Globalization.NumberStyles.HexNumber);

        // BLACK
        if (r == 0 && g == 0 && b == 0)
        {
            computedK = 1;
            return new[] { 0, 0, 0, computedK };
        }

        computedC = 1 - (r / 255);
        computedM = 1 - (g / 255);
        computedY = 1 - (b / 255);

        var minCMY = Math.Min(computedC, Math.Min(computedM, computedY));

        computedC = (computedC - minCMY) / (1 - minCMY);
        computedM = (computedM - minCMY) / (1 - minCMY);
        computedY = (computedY - minCMY) / (1 - minCMY);
        computedK = minCMY;

        return new[] { computedC, computedM, computedY, computedK };
    }
 }


回答5:

I think photoshop uses profile based conversions. Have a look at the documentation for the color options. If it is the case you won't be able to match this behavior with simple formula based solutions.

I have found LCMS to be very handy, simple and efficient for this kind of task.I don't known if there is any .net binding for it...



回答6:

I agree with the previous answers, but I want to say that:

if ( K == 1 ) 
{ 
   C = 0
   M = 0
   Y = 0
} 

It can be if r = g = b = 0.