从UIColor预设中获取RGB值
我的应用程序,我将RGB颜色值传递给服务器。 我的应用程序使用UIColor预定义值,如[UIColor grayColor],[UIColor redColor]。 我知道我可以使用下面的代码:
const CGFloat *c = CGColorGetComponents(color.CGColor)
但只适用于RBG色彩空间的颜色,但是[UIColor grayColor]不是。
有没有办法获得非RBG颜色的RGB值?
谢谢!
UIColor有一个方法可以让你在iOS 7或更高版本上使用RGB组件( -getRed:green:blue:alpha:
。 在iOS 6和更早版本中,如果颜色不在RGB颜色空间中,则此方法将失败并返回NO
(如同[UIColor grayColor]
。
对于iOS 6及更早版本,我所知道的唯一可以在所有色彩空间中工作的方法是在RGB色彩空间中创build一个Core Graphics位图上下文,并使用您的颜色进行绘制。 然后可以从结果位图中读出RGB值。 请注意,这将不适用于某些颜色,如图案颜色(例如[UIColor groupTableViewBackgroundColor]),它们没有合理的RGB值。
- (void)getRGBComponents:(CGFloat [3])components forColor:(UIColor *)color { CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB(); unsigned char resultingPixel[4]; CGContextRef context = CGBitmapContextCreate(&resultingPixel, 1, 1, 8, 4, rgbColorSpace, kCGImageAlphaNoneSkipLast); CGContextSetFillColorWithColor(context, [color CGColor]); CGContextFillRect(context, CGRectMake(0, 0, 1, 1)); CGContextRelease(context); CGColorSpaceRelease(rgbColorSpace); for (int component = 0; component < 3; component++) { components[component] = resultingPixel[component] / 255.0f; } }
你可以像这样使用它:
CGFloat components[3]; [self getRGBComponents:components forColor:[UIColor grayColor]]; NSLog(@"%f %f %f", components[0], components[1], components[2]);
我只知道一个正确的方法来做到这一点 – 那就是调用CGGetColorComponents()
。 我曾尝试使用UIColor
的-getRed:green:blue:alpha
,但在灰阶色彩上无法正常工作。 所以这就是我所做的:
首先,我有一个简单的struct
,可以让我轻松操作RGBA颜色。 这种结构在其他地方用于做各种颜色处理的东西,如伽马校正和颜色平均。
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;
然后,我有一个函数,返回给定一个UIColor
的RGBA
结构。
RGBA RGBAFromUIColor(UIColor *color) { return RGBAFromCGColor(color.CGColor); }
它将UIColor
的CGColor
给一个较低级别的function来完成繁重的工作。
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; }
所以,这对灰度颜色(如UIColor.whiteColor
, UIColor.blackColor
, UIColor.grayColor
等)以及任何红/绿/蓝/ alpha颜色很好。 然而,它不会与HSB颜色一起使用。
添加到Jesse的答案,这里是如何保留alpha:
- (void)getRGBAComponents:(CGFloat [4])components forColor:(UIColor *)color { CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB(); unsigned char resultingPixel[4] = {0}; CGContextRef context = CGBitmapContextCreate(&resultingPixel, 1, 1, 8, 4, rgbColorSpace, kCGImageAlphaPremultipliedLast); CGContextSetFillColorWithColor(context, [color CGColor]); CGContextFillRect(context, CGRectMake(0, 0, 1, 1)); CGContextRelease(context); CGColorSpaceRelease(rgbColorSpace); CGFloat a = resultingPixel[3] / 255.0; CGFloat unpremultiply = (a != 0.0) ? 1.0 / a / 255.0 : 0.0; for (int component = 0; component < 3; component++) { components[component] = resultingPixel[component] * unpremultiply; } components[3] = a; }
从我对“如何将颜色从一个颜色空间转换到另一个颜色空间?”的答案交叉点? 。
要识别不同的颜色空间,您可以从颜色的CGColorSpaceRef
获取CGColorSpaceRef
:
UIColor* color = some color; CGColorSpaceRef colorSpace = CGColorGetColorSpace([color CGColor]); CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace);
然后你可以比较colorSpaceModel
和CoreGraphics/CGColorSpace.h
定义的常量。 UIColor的getRed:green:blue:alpha
适用于kCGColorSpaceModelRGB
,而getWhite:alpha
适用于kCGColorSpaceModelMonochrome
。
你可以简单地通过使用这个获得RGB值
UIColor *chooseColor = view.backgroundColor; CGFloat red,green,blue,alpha; [chooseColor getRed:&red green:&green blue:&blue alpha:&alpha];
谢谢 :-)