从UIColor预设中获取RGB值

lst*_*kov 19 iphone objective-c uicolor cgcolorspace

我的应用程序我将RGB颜色值传递给服务器.我的应用程序使用UIColor预定义值,如[UIColor grayColor],[UIColor redColor].我知道我可以使用以下代码:

const CGFloat *c = CGColorGetComponents(color.CGColor)
Run Code Online (Sandbox Code Playgroud)

但是,仅适用于RBG色彩空间中的颜色,[UIColor grayColor]不是.

有没有办法获得非RBG颜色的RGB值?

谢谢!

Jes*_*sak 44

UIColor有一个方法可以为你提供-getRed:green:blue:alpha:在iOS 7或更高版本上运行良好的RGB组件().在iOS 6及更早版本中,NO如果颜色不在RGB颜色空间中,此方法将失败并返回(就像它一样[UIColor grayColor].)

对于iOS 6及更早版本,我知道在所有颜色空间中工作的唯一方法是在RGB颜色空间中创建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;
    }
}
Run Code Online (Sandbox Code Playgroud)

你可以使用这样的东西:

    CGFloat components[3];
    [self getRGBComponents:components forColor:[UIColor grayColor]];
    NSLog(@"%f %f %f", components[0], components[1], components[2]);
Run Code Online (Sandbox Code Playgroud)

  • 注意:在iOS 5中,`UIColor`的`-getRed:green:blue:alpha`仅适用于使用RGB色彩空间的颜色.对于灰度颜色它是破碎的.他们是否已在iOS 6中修复此问题? (5认同)
  • @damian - 我同意,我很傻到为什么当答案一般是错误的并且只有RGB颜色正确时,答案会越来越高.如果你调用一个颜色对象,它是通过调用`UIColor.blackColor`或`UIColor.whiteColor`获得的(在很多情况下你将无法知道),它会失败并且非常难以诊断.你指出,代码是错误的.(杰西没有违法行为.) (3认同)
  • 看来从iOS7开始(我在iOS7和iOS8上测试过),getRed:green:blue:alpha:方法将与UIDeviceWhiteColorSpace一起使用.但iOS6及更早版本并非如此. (2认同)

Tod*_*man 7

我只知道一种正确的方法 - 这就是打电话CGGetColorComponents().我试过使用UIColor's -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;
Run Code Online (Sandbox Code Playgroud)

然后,我有一个返回RGBA给定a 的结构的函数UIColor.

RGBA RGBAFromUIColor(UIColor *color)
{
  return RGBAFromCGColor(color.CGColor);
}
Run Code Online (Sandbox Code Playgroud)

它传递UIColorCGColor一个低级别的功能做繁重.

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;
}
Run Code Online (Sandbox Code Playgroud)

所以,这个伟大工程的灰度颜色(如UIColor.whiteColor,UIColor.blackColor,UIColor.grayColor,等)以及任何红/绿/蓝/ Alpha颜色.但是,它不适用于HSB颜色.

  • @nschmidt - 你为什么把它标记下来?我回答了这个问题.他想要非RGB颜色(特别是单色)的RGB值,这正是我给出的.如果您将函数传递给RGB颜色,则会获得RGB值.如果您将灰色值(例如,单色)传递给它,您仍然会获得RGB值.仔细阅读答案,你会发现两者都得到了妥善处理.这是我使用的生产代码片段,所以我知道它有效.另外,正如我在评论中指出的那样,您的答案会给出不正确的结果.我并没有因为那个而让你失望,但是......你想要我吗? (2认同)
  • 我想降价将是因为你识别色彩空间模型的方式.例如,3-或4-组分颜色可能在LAB或HSB颜色空间中. (2认同)
  • 好的解决方案 谢谢! (2认同)