2013-02-16 9 views
3

Я травляю в Интернете решение, но сумел найти тот, который работает.UIColor CMYK и Lab Values?

Простой вопрос, более чем вероятно, сложный ответ:

Как я могу получить CMYK и Lab значения из объекта UIColor (из которых я знаю, значения 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); 

Любая помощь очень ценится, спасибо.

+0

См http://stackoverflow.com/questions/4858131/rgb-to-cmyk-and-back-algorithm?rq=1 Это для Java, но основы применяются. – rmaddy

+0

Я также думал, что преобразование цвета на основе ICC - это правильная вещь. Но API ColorSync недоступен в iOS (и устарел на OS X 10.6). –

+0

@Josh Kahane: Формула преобразования цвета, которую вы вставили, можно найти по всему Интернету. Тем не менее, поскольку преобразование цвета далека от простой системы, которая может быть записана в одной формуле, результат формулы будет плохим и бесполезным. Невозможно использовать цветовые профили. – Codo

ответ

5

Для преобразования цвета на основе ICC вы можете использовать Little Color Management System. (Я только что добавили все .c и .h файлы из архива загрузки в проект IOS Xcode Составлен и побежал следующий код без проблем.).

Примечание: RGB и CMYK являются устройством, зависит цветовые пространства, Лаборатория - это устройство независимое цветовое пространство. Поэтому для преобразования из RGB в Lab вам необходимо выбрать независимое от устройства (или «откалиброванное») цветовое пространство RGB для преобразования, например sRGB.

Little CMS поставляется со встроенными профилями для цветовых пространств sRGB и Lab. Преобразование из SRGB Лабораторию выглядит следующим образом:

Создание цветовой трансформации:

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. 

Dispose преобразования цвета:

cmsDeleteTransform(xform); 

Конечно , преобразование будет создано только один раз и будет использоваться для всех преобразований цветов.

Для преобразования RGB в CMYK вы также можете использовать Little CMS, но вы должны предоставить ICC-профиль, например. один из бесплатной страницы загрузки Adobe ICC profile downloads for Mac OS.

Пример кода для перевода в формат 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); 
+0

Любопытно, что iOS использует sRGB в качестве цветового пространства дисплея? – guitarflow

+0

@guitarflow: Я не знаю (и я даже не знаю, зарегистрировано ли это). Я взял sRGB в качестве примера в коде, потому что он широко используется. Но я отредактирую свой ответ, чтобы сделать это более ясным. –

+0

А, ок. Благодарю. Я предположил, что UIScreen также имеет цветовое пространство, к которому можно запросить. Похоже, это не так. Поэтому вы должны принять цветовое пространство. Думаю, sRGB будет хорошим предположением. – guitarflow

1

Чтобы получить значения 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; 
} 
+0

Привет, Натан, у вас тоже есть код для обратного направления? –