I only know of one correct way to do this — and that is to call CGGetColorComponents()
. I have tried using UIColor
's -getRed:green:blue:alpha
, but it does not work correctly on grayscale colors. So here is what I do:
First, I have a simple struct
that lets me manipulate RGBA colors easily. This structure is useful elsewhere for doing all sorts of color manipulation stuff like gamma correction and color averaging.
typedef struct
{
CGFloat r; // Red component (0 <= r <= 1)
CGFloat g; // Green component (0 <= g <= 1)
CGFloat b; // Blue component (0 <= b <= 1)
CGFloat a; // Alpha/opacity component (0 <= a <= 1)
}
RGBA;
Then, I have a function that returns an RGBA
structure given a UIColor
.
RGBA RGBAFromUIColor(UIColor *color)
{
return RGBAFromCGColor(color.CGColor);
}
It passes the UIColor
's CGColor
to a lower-level function to do the heavy lifting.
RGBA RGBAFromCGColor(CGColorRef color)
{
RGBA rgba;
CGColorSpaceRef color_space = CGColorGetColorSpace(color);
CGColorSpaceModel color_space_model = CGColorSpaceGetModel(color_space);
const CGFloat *color_components = CGColorGetComponents(color);
int color_component_count = CGColorGetNumberOfComponents(color);
switch (color_space_model)
{
case kCGColorSpaceModelMonochrome:
{
assert(color_component_count == 2);
rgba = (RGBA)
{
.r = color_components[0],
.g = color_components[0],
.b = color_components[0],
.a = color_components[1]
};
break;
}
case kCGColorSpaceModelRGB:
{
assert(color_component_count == 4);
rgba = (RGBA)
{
.r = color_components[0],
.g = color_components[1],
.b = color_components[2],
.a = color_components[3]
};
break;
}
default:
{
NSLog(@"Unsupported color space model %i", color_space_model);
rgba = (RGBA) { 0, 0, 0, 0 };
break;
}
}
return rgba;
}
So, this works great for grayscale colors (like UIColor.whiteColor
, UIColor.blackColor
, UIColor.grayColor
, etc.) as well as any red/green/blue/alpha color. It won't work with HSB colors, however.