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 )`
For CGColor
you can use the function CGColorEqualToColor
:
bool CGColorEqualToColor (
CGColorRef color1,
CGColorRef color2
);
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;
}
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)
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With