iphone - gama - ¿Cómo convertir colores de un espacio de color a otro?
amplia gama de colores(p3) (4)
En swift 3 podemos usar directamente.
let colorSpace = uiColor.cgColor.colorSpace
let csModel = colorSpace.model
para obtener el espacio de color y el modelo de espacio de color de un UIColor
.
¿Existe una forma de Cocoa Touch para convertir colores de un espacio de color a otro?
Al final de este código:
UIColor *grey = [UIColor colorWithWhite: 0.5 alpha: 1.0];
CGColorRef greyRef = [grey CGColor];
int x = CGColorGetNumberOfComponents(greyRef);
... x
es 2.
La razón por la que necesito esto es que estoy intentando copiar colores a una lista de componentes de color para CGGradientCreateWithColorComponents
, que necesita todos los colores en un solo espacio de color. El problema es que el gris está en el espacio de color en escala de grises, en lugar del RGB. (El nombre se me escapa en este momento, pero no es importante).
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;
}
Sé que puedo buscar colores en el espacio de color en escala de grises y convertirlos. Pero eso solo resuelve un caso. Mirando esta pregunta , creo que HSB también se maneja. Pero me gustaría escribir un código aquí y nunca volver a pensar en ello, lo que significa no solo admitir los espacios de color que hay ahora, sino todo lo que Apple pueda agregar en el futuro. ¿Estoy fuera de suerte?
No estoy seguro de cómo convertirlos automáticamente, pero para identificar diferentes espacios de color puede obtener el CGColorSpaceModel
desde el color CGColorSpaceRef
:
UIColor* color = some color;
CGColorSpaceRef colorSpace = CGColorGetColorSpace([color CGColor]);
CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace);
Luego puede comparar colorSpaceModel
con las constantes definidas en CoreGraphics/CGColorSpace.h
. GetRed getRed:green:blue:alpha
de kCGColorSpaceModelRGB
funciona para kCGColorSpaceModelRGB
, mientras que getWhite:alpha
funciona para kCGColorSpaceModelMonochrome
.
Tenga en cuenta que un UIColor
que se creó con colorWithHue:saturation:brightness:alpha:
estará en el espacio de color RGB.
Otra forma de convertirlos es dibujarlos en contextos y dejar que los gráficos principales hagan la conversión por usted. Vea mi respuesta a esta pregunta:
Para los colores creados con [UIColor colorWithRed:green:blue:alpha:]
, puede usar UIColor getRed:green:blue:alpha:
descrito en UIColor Class Reference . Es parte de iOS 5 y versiones posteriores.
Si el color se creó con colorWithWhite:alpha:
puede usar getWhite:alpha:
lugar, descrito en UIColor Class Reference .
Para determinar qué espacio de color se está utilizando, puede usar CGColorGetColorSpace([color colorSpace])
. Pero probablemente sea más fácil simplemente verificar el resultado de la llamada al método, y luego pasar al siguiente intento. Algo como esto:
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
}
No sé cómo manejar las constantes de color como [UIColor lightGrayColor]
, aparte de dibujarlas en un mapa de bits temporal y detectarlas. Algunas de estas constantes de color son en realidad texturas; Tu mejor apuesta es probablemente evitarlos.
Si planeas hacer esto mucho, es un uso apropiado de una categoría:
@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