2011-05-22 2 views
14

У меня проблема с сопоставлением UIColors. У меня есть изображение, которое я успешно извлек цвет на изображении, на которое пользователь нажал. Теперь я хочу сравнить этот цвет с другими цветами, но я получаю некоторые странные результаты. Вот что я пытался:Сравнение UIColors или CGColor или CGColorSpace

CGColorRef pixelColor = [[buttonImage colorAtPixel:point] CGColor]; 
UIColor* color = [UIColor colorWithCGColor:pixelColor]; 
UIColor* aqua = [UIColor colorWithRed:0.521569 green:0.768627 blue:0.254902 alpha:1]; 
if (CGColorEqualToColor(color.CGColor, aqua.CGColor)) { 
    DLog(@"Apparently, it works"); 
} 
DLog(@"%@", color.CGColor); 
DLog(@"%@", aqua.CGColor); 

Выход:

2011-05-21 19:48:27.144 Coffee[66860:207] -[DescriptorsViewController touchesEnded:withEvent:] <CGColor 0x4d1eb80> [<CGColorSpace 0x4d1a070> (kCGColorSpaceDeviceRGB)] (0.521569 0.768627 0.254902 1) 
2011-05-21 19:48:27.145 Coffee[66860:207] -[DescriptorsViewController touchesEnded:withEvent:] <CGColor 0x4d1f750> [<CGColorSpace 0x4d1a070> (kCGColorSpaceDeviceRGB)] (0.521569 0.768627 0.254902 1) 

Похоже адреса CGColor различны, но CGColorSpaces то же самое, но я не могу понять, как сравнить CGColorSpaces

Я также попытался это:

CGColorRef pixelColor = [[buttonImage colorAtPixel:point] CGColor]; 
UIColor* color = [UIColor colorWithCGColor:pixelColor]; 
UIColor* aqua = [UIColor colorWithRed:0.521569 green:0.768627 blue:0.254902 alpha:1]; 
if ([color isEqual:aqua]) { 
    DLog(@"Apparently, it works"); 
} 
DLog(@"%@", color.CGColor); 
DLog(@"%@", aqua.CGColor); 

То же самое происходит глупостью.

2011-05-21 20:02:49.277 Coffee[67013:207] -[DescriptorsViewController touchesEnded:withEvent:] <CGColor 0x4d3b810> [<CGColorSpace 0x5912010> (kCGColorSpaceDeviceRGB)] (0.521569 0.768627 0.254902 1) 
2011-05-21 20:02:49.278 Coffee[67013:207] -[DescriptorsViewController touchesEnded:withEvent:] <CGColor 0x4d3ba20> [<CGColorSpace 0x5912010> (kCGColorSpaceDeviceRGB)] (0.521569 0.768627 0.254902 1)` 

ответ

2

Вы можете получить и сравнить цветовые пространства, используя следующий:

CGColorSpaceModel aquaCm = CGColorSpaceGetModel(CGColorGetColorSpace([UIColor aquaColor].CGColor); 
CGColorSpaceModel cm = CGColorSpaceGetModel(CGColorGetColorSpace(pixelColor); 

if (aquaCm == cm) { 
    //compare colors in the same colorspace here 
} 

Для цветов, которые не в том же цветовом, вы можете конвертировать их в соответствующем цветовом как показаны in this question OR, поскольку вы» повторите сравнение цветов с цветами системы, сравните цвета, сгенерированные с помощью [UIColor colorWithRed:green:blue:alpha:] (которые находятся в цветовом пространстве RGB, скорее всего, каково ваше изображение)

1

Я бы просто создал объекты UIColor для них, а затем используйте -(BOOL)getRed:(CGFloat *)red green:(CGFloat *)green blue:(CGFloat *)blue alpha:(CGFloat *)alpha, чтобы получить компоненты и сравнить. Обратите внимание, что возможно иметь ошибки округления, в зависимости от того, откуда идут другие цвета, поэтому вы можете потребовать, чтобы все цветовые компоненты были правильными только в пределах +/- 1/256.0

16

Для CGColor вы можете использовать функцию CGColorEqualToColor:

bool CGColorEqualToColor (
    CGColorRef color1, 
    CGColorRef color2 
); 
+0

Это все! Спасибо ... – StefMa

+0

К сожалению, CGColorEqualToColor НЕ работает, как показано в исходном вопросе. У меня сейчас такая же проблема. Странно, что он работает на iPhone 5 и ниже (симулятор и устройство тестировалось), но не на 5 и выше (только для симулятора). – Dylan

4

Я также засвидетельствовал, что эта функция не работает! Кто-нибудь сообщил об этом яблоку?

Мое решение было сравнить отдельные RGBA - вот код (я реализовал категорию, следовательно self является UIColor).

Я также обнаружил, что ошибки округления могут привести к прямым сравнениям с ошибкой CGFloat. Поэтому я бросил их в ints.

-(bool)isEqualToColor:(UIColor*)other 
{ 
    CGFloat fLHS[4]; 
    CGFloat fRHS[4]; 

    [self getRed:&fLHS[0] green:&fLHS[1] blue:&fLHS[2] alpha:&fLHS[3]]; 
    [other getRed:&fRHS[0] green:&fRHS[1] blue:&fRHS[2] alpha:&fRHS[3]]; 

    // reduce rounding errors - convert all into int for compare 
    for(int i=0;i<4;i++) 
    { 
     if(((int)(fLHS[i]*255))!=((int)(fRHS[i]*255))) 
      return false; 
    } 
    return true; 
} 
+1

Это работает правильно для меня. – jboulter11

+1

Это сработало. Спасибо брат. – steveluoxin

Смежные вопросы