19

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

const CGFloat *c = CGColorGetComponents(color.CGColor)

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

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

谢谢!

4

5 回答 5

44

UIColor 有一种方法可以为您提供-getRed:green:blue:alpha:在 iOS 7 或更高版本上运行良好的 RGB 组件 ( )。NO在 iOS 6 和更早版本上,如果颜色不在 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;
    }
}

你可以像这样使用它:

    CGFloat components[3];
    [self getRGBComponents:components forColor:[UIColor grayColor]];
    NSLog(@"%f %f %f", components[0], components[1], components[2]);
于 2011-01-15T15:06:34.490 回答
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;

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

RGBA RGBAFromUIColor(UIColor *color)
{
  return RGBAFromCGColor(color.CGColor);
}

它将UIColor'sCGColor传递给较低级别​​的函数来完成繁重的工作。

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.whiteColorUIColor.blackColorUIColor.grayColor等)以及任何红色/绿色/蓝色/alpha 颜色。但是,它不适用于 HSB 颜色。

于 2013-05-19T09:14:56.060 回答
3

添加到杰西的答案,这里是如何保留阿尔法:

- (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;
}
于 2013-01-24T17:47:02.370 回答
1

我对“如何将颜色从一种颜色空间转换为另一种颜色空间?”的回答中交叉发布 .

要识别不同的颜色空间,您可以CGColorSpaceModel从颜色中获取CGColorSpaceRef

UIColor* color = some color;
CGColorSpaceRef colorSpace = CGColorGetColorSpace([color CGColor]);
CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace);

然后你可以colorSpaceModel与定义的常量进行比较CoreGraphics/CGColorSpace.h。UIColorgetRed:green:blue:alpha适用于kCGColorSpaceModelRGB,而getWhite:alpha适用于kCGColorSpaceModelMonochrome.

于 2013-06-07T10:30:58.517 回答
0

您可以简单地使用它来获取 RGB 值

UIColor *chooseColor = view.backgroundColor;
CGFloat red,green,blue,alpha;

[chooseColor getRed:&red green:&green blue:&blue alpha:&alpha]; 

谢谢 :-)

于 2014-06-13T10:35:26.220 回答