Получить значение RGB из пресетов UIColor
В моем приложении я передаю значение цвета RGB на сервер. Мое приложение использует предопределенные значения UIColor, такие как [UIColor grayColor], [UIColor redColor]. Я знаю, что могу использовать следующий код:
const CGFloat *c = CGColorGetComponents(color.CGColor)
но только для цветов в цветовом пространстве RBG [UIColor grayColor] нет.
Есть ли способ получить значения RGB для не-RBG цветов?
Спасибо!
5 ответов
У 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]);
Я знаю только один правильный способ сделать это - это позвонить 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
структура с учетом UIColor
,
RGBA RGBAFromUIColor(UIColor *color)
{
return RGBAFromCGColor(color.CGColor);
}
Это проходит UIColor
"s 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.
В дополнение к ответу Джесси, вот как сохранить альфа:
- (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;
}
Перекрестный пост из моего ответа на вопрос "Как преобразовать цвета из одного цветового пространства в другое?",
Для идентификации различных цветовых пространств вы можете получить CGColorSpaceModel
из цвета 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];
Спасибо:-)