Получить значение RGB из пресетов UIColor - PullRequest
19 голосов
/ 15 января 2011

В моем приложении я передаю значение цвета RGB на сервер. Мое приложение использует предопределенные значения UIColor, такие как [UIColor grayColor], [UIColor redColor]. Я знаю, что могу использовать следующий код:

const CGFloat *c = CGColorGetComponents(color.CGColor)

но только для цветов, которые находятся в цветовом пространстве RBG, однако [UIColor grayColor] не является.

Есть ли способ получить значения RGB для не-RBG цветов?

Спасибо!

Ответы [ 5 ]

44 голосов
/ 15 января 2011

В UIColor есть метод, который дает вам компоненты RGB (-getRed:green:blue:alpha:), который отлично работает на iOS 7 или выше. В iOS 6 и более ранних версиях этот метод завершится ошибкой и вернет NO, если цвет не находится в цветовом пространстве RGB (как это будет для [UIColor grayColor].)

Для iOS 6 и более ранних версий единственный известный мне способ работы с этим, который работает во всех цветовых пространствах, - это создать растровый контекст Core Graphics в цветовом пространстве RGB и нарисовать его своим цветом. Затем вы можете прочитать значения 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]);
7 голосов
/ 19 мая 2013

Я знаю только один правильный способ сделать это - это позвонить 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;

Затем у меня есть функция, которая возвращает структуру RGBA, заданную UIColor.

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

Он передает UIColor CGColor в функцию более низкого уровня для выполнения тяжелой работы.

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 и т. Д.), А также любой красный / зеленый / синий / альфа-цвет.Однако он не будет работать с цветами HSB.

3 голосов
/ 24 января 2013

В дополнение к ответу Джесси, вот как сохранить альфа:

- (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;
}
1 голос
/ 07 июня 2013

Перекрестно из мой ответ на вопрос «Как преобразовать цвета из одного цветового пространства в другое?» .

Чтобы определить различные цветовые пространства, вы можете получить CGColorSpaceModel из цвета CGColorSpaceRef:

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

Затем вы можете сравнить colorSpaceModel с константами, определенными в CoreGraphics/CGColorSpace.h.getRed:green:blue:alpha UIColor работает для kCGColorSpaceModelRGB, тогда как getWhite:alpha работает для kCGColorSpaceModelMonochrome.

0 голосов
/ 13 июня 2014

Вы можете получить значение RGB просто используя это

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

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

спасибо :-)

...