UIColor CMYK和Lab值

3

简单的问题,很可能有复杂的答案:

如何从UIColor对象中获取CMYK和Lab值(如果知道RGB值是否有帮助)?

我找到了关于获取CMYK值的内容,但是尽管它无处不在,我无法得到任何准确的值,我听说这不是一个好的代码片段。

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);

请参考以下链接:https://dev59.com/kW445IYBdhLWcg3wcJ6O?rq=1,该链接提供了Java的相关内容,但基本原理适用于其他编程语言。 - rmaddy
我也认为基于ICC的颜色转换是正确的选择。但是ColorSync API在iOS上不可用(并且自OS X 10.6起已被弃用)。 - Martin R
@Josh Kahane:你粘贴的颜色转换公式在网上随处可见。然而,由于颜色转换远非简单的系统可以用单一公式捕捉,所以公式的结果将是差劲和无用的。没有绕开使用颜色配置文件的方法。 - Codo
@JoshKahane:我的回答有帮到你吗?你需要更多的信息吗? - Martin R
抱歉@MartinR,我被其他工作卡住了,完全忘记了这件事。我稍后会尝试您的解决方案,并尽快向您反馈结果。 - Josh Kahane
2个回答

5
对于基于ICC的颜色转换,您可以使用Little Color Management System。(我刚刚将下载存档中的所有.c和.h文件添加到了iOS Xcode项目中。它编译并运行以下代码没有问题。)
注:RGB和CMYK是设备相关的颜色空间,而Lab是设备无关的颜色空间。因此,要将RGB转换为Lab,必须选择设备无关(或“校准”)的RGB颜色空间进行转换,例如sRGB。
Little CMS带有sRGB和Lab颜色空间的内置配置文件。从sRGB到Lab的转换如下所示:
创建一个颜色转换:
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);

转换颜色:

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

处理颜色转换:

cmsDeleteTransform(xform);

当然,这个转换只需要创建一次,就可以用于所有的颜色转换。
对于RGB到CMYK的转换,您也可以使用Little CMS,但您必须提供一个ICC文件,例如从免费的Adobe下载页面ICC profile downloads for Mac OS中下载一个。
RGB到CMYK转换的代码示例:
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);

只是好奇,iOS是否使用sRGB作为显示颜色空间? - guitarflow
1
@JoshKahane:我将以下文件从lcms添加到Xcode项目中:来自include目录的lcms2.h和lcms2_plugin.h,来自src目录的所有.c和.h文件。这就是你需要的库。在你的代码中,你只需要#include "lcms2.h"。-希望这有所帮助,否则请告诉我。 - Martin R
原来是因为(如上面的示例代码),使用了 cmsCreateLab4Profile,而对于 Photoshop Lab 颜色复制,您应该使用 cmsCreateLab2Profile - Josh Kahane
@JoshKahane:谢谢您提供的信息!您在将其转换为CMYK时成功了吗? - Martin R
1
@guitarflow 和 Martin,似乎从 iPhone 5 开始,苹果声称屏幕具有完整的 sRGB 色域(它非常接近:AnandTechMark Meyer)。然而,我仍然很好奇,我们是否可以获得设备的颜色配置文件!使用其他配置文件将 RGB 转换为 Lab 看起来对我来说有些棘手。 - Warpling
显示剩余12条评论

2
要获取LAB值,您需要将RGB值转换为XYZ值,然后再将其转换为RGB值。
- (NSMutableArray *) convertRGBtoLABwithColor: (UIColor *)color



////make variables to get rgb values
CGFloat red3;
CGFloat green3;
CGFloat blue3;
//get rgb of color
[color getRed:&red3 green:&green3 blue:&blue3 alpha:nil];

float red2 = (float)red3*255;
float blue2 = (float)blue3*255;
float green2 = (float)green3*255;

//first convert RGB to XYZ

// same values, from 0 to 1
red2 = red2/255;
green2 = green2/255;
blue2 = blue2/255;

// adjusting values
if(red2 > 0.04045)
{
    red2 = (red2 + 0.055)/1.055;
    red2 = pow(red2,2.4);
} else {
    red2 = red2/12.92;
}

if(green2 > 0.04045)
{
    green2 = (green2 + 0.055)/1.055;
    green2 = pow(green2,2.4);
} else {
    green2 = green2/12.92;
}

if(blue2 > 0.04045)
{
    blue2 = (blue2 + 0.055)/1.055;
    blue2 = pow(blue2,2.4);
} else {
    blue2 = blue2/12.92;
}

red2 *= 100;
green2 *= 100;
blue2 *= 100;

//make x, y and z variables
float x;
float y;
float z;

// applying the matrix to finally have XYZ
x = (red2 * 0.4124) + (green2 * 0.3576) + (blue2 * 0.1805);
y = (red2 * 0.2126) + (green2 * 0.7152) + (blue2 * 0.0722);
z = (red2 * 0.0193) + (green2 * 0.1192) + (blue2 * 0.9505);

//then convert XYZ to LAB

x = x/95.047;
y = y/100;
z = z/108.883;

// adjusting the values
if(x > 0.008856)
{
    x = powf(x,(1.0/3.0));
} else {
    x = ((7.787 * x) + (16/116));
}

if(y > 0.008856)
{
    y = pow(y,(1.0/3.0));
} else {
    y = ((7.787 * y) + (16/116));
}

if(z > 0.008856)
{
    z = pow(z,(1.0/3.0));
} else {
    z = ((7.787 * z) + (16/116));
}

//make L, A and B variables
float l;
float a;
float b;

//finally have your l, a, b variables!!!!
l = ((116 * y) - 16);
a = 500 * (x - y);
b = 200 * (y - z);

NSNumber *lNumber = [NSNumber numberWithFloat:l];
NSNumber *aNumber = [NSNumber numberWithFloat:a];
NSNumber *bNumber = [NSNumber numberWithFloat:b];

//add them to an array to return.
NSMutableArray *labArray = [[NSMutableArray alloc] init];
[labArray addObject:lNumber];
[labArray addObject:aNumber];
[labArray addObject:bNumber];

return labArray;
}

嗨,Nathan,你是否也有反向的代码? - Captain Fim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接