Как преобразовать цвета из одного цветового пространства в другое?
Есть ли способ Cocoa Touch для преобразования цветов из одного цветового пространства в другое?
В конце этого кода:
UIColor *grey = [UIColor colorWithWhite: 0.5 alpha: 1.0];
CGColorRef greyRef = [grey CGColor];
int x = CGColorGetNumberOfComponents(greyRef);
... x
равно 2.
Причина, по которой мне это нужно, я пытаюсь скопировать цвета в список цветных компонентов для CGGradientCreateWithColorComponents
, которым нужны все цвета в одном цветовом пространстве. Проблема в том, что серый цвет находится в оттенке серого, а не в RGB. (В настоящее время имя ускользает от меня, но это не важно.)
CGGradientRef createGradient(NSInteger inCount, NSArray* inColors, CGFloat* inLocations) {
CGColorSpaceRef theColorspace = CGColorSpaceCreateDeviceRGB( );
size_t numberOfComponents = 4;
NSInteger colorSize = numberOfComponents * sizeof( CGFloat );
CGFloat *theComponents = malloc( inCount * colorSize );
CGFloat *temp = theComponents;
for ( NSInteger i = 0; i < inCount; i++ ) {
UIColor *theColor = [inColors objectAtIndex: i];
CGColorRef cgColor = [theColor CGColor];
const CGFloat *components = CGColorGetComponents( cgColor );
memmove( temp, components, colorSize );
temp += numberOfComponents;
}
CGGradientRef gradient = CGGradientCreateWithColorComponents( theColorspace,
theComponents, inLocations, inCount );
CGColorSpaceRelease( theColorspace );
free( theComponents );
return gradient;
}
Я знаю, что я могу искать цвета в цветовом пространстве оттенков серого и преобразовывать их. Но это решает только один случай. От поиска по этому вопросу, я думаю, HSB также обрабатывается. Но я хотел бы написать здесь какой-нибудь код и никогда больше не думать об этом, а значит, поддерживать не только цветовые пространства, которые есть сейчас, но и все, что Apple может добавить в будущем. Мне повезло?
Ответы
Ответ 1
Я не уверен, как автоматически их преобразовать, но для определения разных цветовых пространств вы можете получить 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
.
Обратите внимание, что UIColor
, созданный с помощью colorWithHue:saturation:brightness:alpha:
, будет в цветовом пространстве RGB.
Ответ 2
Для цветов, созданных с помощью [UIColor colorWithRed:green:blue:alpha:]
, вы можете использовать UIColor getRed:green:blue:alpha:
, описанный в Справочник класса UIColor. Это часть iOS 5 и более поздних версий.
Если цвет был создан с помощью colorWithWhite:alpha:
, вы можете использовать getWhite:alpha:
вместо этого, описанный в Ссылка на класс UIColor.
Чтобы определить, какое цветовое пространство используется, вы можете использовать CGColorGetColorSpace([color colorSpace])
. Но, вероятно, проще просто проверить результат вызова метода, а затем перейти к следующей попытке. Что-то вроде этого:
if ([color getRed:&red green:&green blue:&blue alpha:&alpha]) {
// red, green and blue are all valid
} else if if ([color getWhite:&white alpha:&alpha]) {
red = white; green = white; blue = white;
} else {
// can't get it
}
Я не знаю, как обрабатывать цветовые константы, такие как [UIColor lightGrayColor]
, кроме рисования их во временное растровое изображение и их обнаружение. Некоторые из этих цветовых констант являются фактически текстурами; лучше всего, чтобы избежать их.
Если вы планируете сделать это много, это подходящее использование категории:
@interface UIColor(sf)
- (BOOL)sfGetRed:(CGFloat *)red green:(CGFloat *)green blue:(CGFloat *)blue alpha:(CGFloat *)alpha;
@end
@implementation UIColor(sf)
- (BOOL)sfGetRed:(CGFloat *)red green:(CGFloat *)green blue:(CGFloat *)blue alpha:(CGFloat *)alpha {
if ([self getRed:red green:green blue:blue alpha:alpha]) return YES;
CGFloat white;
if ([self getWhite:&white alpha:alpha]) {
if (red) *red = white;
if (green) *green = white;
if (blue) *blue = white;
return YES;
}
return NO;
}
@end
Ответ 3
Другим способом преобразования этих данных является привлечение их в контексты и позволяющее преобразовать основные графики в вашу систему. См. Мой ответ на этот вопрос:
Получить значение RGB из пресетов UIColor
Ответ 4
В swift 3 мы можем напрямую использовать
let colorSpace = uiColor.cgColor.colorSpace
let csModel = colorSpace.model
чтобы получить цветовое пространство и модель цветового пространства от UIColor
.