objective-crgbuicolorcmyklab-color-space

UIColor CMYK and Lab Values


Simple question, more than likely complex answer:

How can I get CMYK and Lab values from a UIColor object (of which I know the RGB values if it helps)?

I have found this regarding getting CMYK values but I can't get any accurate values out of it, despite it being everywhere, I've heard it's not a great snippet.

CGFloat rgbComponents[4];
    [color getRed:&rgbComponents[0] green:&rgbComponents[1] blue:&rgbComponents[2] alpha:&rgbComponents[3]];

    CGFloat k = MIN(1-rgbComponents[0], MIN(1-rgbComponents[1], 1-rgbComponents[2]));
    CGFloat c = (1-rgbComponents[0]-k)/(1-k);
    CGFloat m = (1-rgbComponents[1]-k)/(1-k);
    CGFloat y = (1-rgbComponents[2]-k)/(1-k);

Solution

  • For ICC-based color conversion, you can use the Little Color Management System. (I have just added all .c and .h files from the download archive to an iOS Xcode project. It compiled and ran the following code without problems.)

    Remark: RGB and CMYK are a device dependent color spaces, Lab is a device independent color space. Therefore, to convert from RGB to Lab, you have to choose a device independent (or "calibrated") RGB color space for the conversion, for example sRGB.

    Little CMS comes with built-in profiles for sRGB and Lab color spaces. A conversion from sRGB to Lab looks like this:

    Create a color transformation:

    cmsHPROFILE rgbProfile = cmsCreate_sRGBProfile();
    cmsHPROFILE labProfile = cmsCreateLab4Profile(NULL);
    cmsHTRANSFORM xform = cmsCreateTransform(rgbProfile, TYPE_RGB_FLT, labProfile,
                                             TYPE_Lab_FLT,
                                             INTENT_PERCEPTUAL, 0);
    cmsCloseProfile(labProfile);
    cmsCloseProfile(rgbProfile);
    

    Convert colors:

    float rgbValues[3];
    // fill rgbValues array with input values ...
    float labValues[3];
    cmsDoTransform(xform, rgbValues, labValues, 1);
    // labValues array contains output values.
    

    Dispose of color transformation:

    cmsDeleteTransform(xform);
    

    Of course, the transformation would be created only once and used for all color conversions.

    For RGB to CMYK conversion you can also use Little CMS, but you have to provide an ICC-Profile, e.g. one from the free Adobe download page ICC profile downloads for Mac OS.

    Code example for RGB to CMYK conversion:

    float rgb[3]; // fill with input values (range 0.0 .. 1.0)
    float cmyk[4]; // output values (range 0.0 .. 100.0)
    
    cmsHPROFILE rgbProfile = cmsCreate_sRGBProfile();
    
    // The CMYK profile is a resource in the application bundle:
    NSString *cmykProfilePath = [[NSBundle mainBundle] pathForResource:@"YourCMYKProfile.icc" ofType:nil];
    cmsHPROFILE cmykProfile = cmsOpenProfileFromFile([cmykProfilePath fileSystemRepresentation], "r");
    
    cmsHTRANSFORM xform = cmsCreateTransform(rgbProfile, TYPE_RGB_FLT, cmykProfile,
                                             TYPE_CMYK_FLT,
                                             INTENT_PERCEPTUAL, 0);
    
    cmsCloseProfile(cmykProfile);
    cmsCloseProfile(rgbProfile);
    
    cmsDoTransform(xform, rgb, cmyk, 1);
    
    cmsDeleteTransform(xform);