Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing UIColors or CGColor or CGColorSpace

Tags:

ios

uicolor

I'm having an issue comparing UIColors. I have an image, which I have successfully extracted the color on the image at which the user clicked. Now I want to compare that color with other colors, but I'm getting some strange results. Here's what I've tried:

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

Output:

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 )

It looks like the CGColor addresses are different, but the CGColorSpaces are the same, but I can't figure out how to compare the CGColorSpaces

I've also tried this:

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

The same silliness occurs.

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 )`
like image 869
wiznaibus Avatar asked May 22 '11 03:05

wiznaibus


4 Answers

For CGColor you can use the function CGColorEqualToColor:

bool CGColorEqualToColor (
   CGColorRef color1,
   CGColorRef color2
);
like image 166
artkoenig Avatar answered Oct 23 '22 08:10

artkoenig


I too have witnessed this function fail to work! Has anyone reported it to apple?

My solution was to compare individual RGBA - here's the code (I implemented a category, hence self is a UIColor).

I also found that rounding errors could make direct comparisons with the CGFloat fail. So I've cast them to 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;
}
like image 20
GilesDMiddleton Avatar answered Oct 23 '22 07:10

GilesDMiddleton


You can get and compare colorspaces using the following:

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

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

For colors that are not in the same colorspace, you can either convert them to the appropriate colorspace as illustrated in this question OR since you're doing color comparisons with system colors, compare against colors generated with [UIColor colorWithRed:green:blue:alpha:] (which are in RGB colorspace, most likely what your image is)

like image 42
Mirkules Avatar answered Oct 23 '22 06:10

Mirkules


I'd just create UIColor objects for them, then use -(BOOL)getRed:(CGFloat *)red green:(CGFloat *)green blue:(CGFloat *)blue alpha:(CGFloat *)alpha to get the components and compare. Note that it's possible to have rounding errors, depending on where the other color's are coming from, so you may want to require each color components to be only correct within +/- 1/256.0

like image 25
zeroimpl Avatar answered Oct 23 '22 08:10

zeroimpl