RGB to CMYK and back algorithm

JF Beaulieu picture JF Beaulieu · Feb 1, 2011 · Viewed 32.6k times · Source

I am trying to implement a solution for calculating the conversion between RGB and CMYK and vice versa. Here is what I have so far:

  public static int[] rgbToCmyk(int red, int green, int blue)
    {
        int black = Math.min(Math.min(255 - red, 255 - green), 255 - blue);

        if (black!=255) {
            int cyan    = (255-red-black)/(255-black);
            int magenta = (255-green-black)/(255-black);
            int yellow  = (255-blue-black)/(255-black);
            return new int[] {cyan,magenta,yellow,black};
        } else {
            int cyan = 255 - red;
            int magenta = 255 - green;
            int yellow = 255 - blue;
            return new int[] {cyan,magenta,yellow,black};
        }
    }

    public static int[] cmykToRgb(int cyan, int magenta, int yellow, int black)
    {
        if (black!=255) {
            int R = ((255-cyan) * (255-black)) / 255; 
            int G = ((255-magenta) * (255-black)) / 255; 
            int B = ((255-yellow) * (255-black)) / 255;
            return new int[] {R,G,B};
        } else {
            int R = 255 - cyan;
            int G = 255 - magenta;
            int B = 255 - yellow;
            return new int[] {R,G,B};
        }
    }

Answer

Lea Verou picture Lea Verou · Feb 1, 2011

To accurately convert values from RGB to CMYK and vice versa, the way Photoshop does, you need to use an ICC color profile. All the simple algorithmic solutions you'll find in the interwebs (like the one posted above) are inacurrate and produce colors that are outside the CMYK color gamut (for example they convert CMYK(100, 0, 0, 0) to rgb(0, 255, 255) which is obviously wrong since rgb(0, 255, 255) can't be reproduced with CMYK). Look into the java.awt.color.ICC_ColorSpace and java.awt.color.ICC_Profile classes for converting colors using ICC color profiles. As for the color profile files themselves, Adobe distributes them for free.