2009-07-08 13 views
17

¿Hay una forma Cocoa Touch para convertir colores de un espacio de color a otro?¿Cómo 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 que necesito esto es que estoy tratando de copiar los 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 de escala de grises, en lugar del RGB. (El nombre se me escapa por el 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. Desde mirar at this question, creo que HSB también se maneja. Pero me gustaría escribir algún código aquí y no volver a pensar en él, lo que significa soportar no solo los espacios de color que hay ahora sino todo lo que Apple podría agregar en el futuro. ¿No tengo suerte?

Respuesta

7

No estoy seguro de cómo convertir de forma automática, sino para identificar los diferentes espacios de color se puede obtener el CGColorSpaceModel a partir de CGColorSpaceRef el color:

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

entonces se puede comparar con colorSpaceModel las constantes definidas en CoreGraphics/CGColorSpace.h. UIColor's getRed:green:blue:alpha 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á realmente en el espacio de color RGB.

+0

Esta es una muy buena respuesta, aunque es posible que desee mencionar que los colores HSB se colocan en el espacio de color RGB. Por lo tanto, es perfectamente válido llamar 'getRed: green: blue: alpha:' en ellos. –

+0

Hmm, no parece haber un 'kCGColorSpaceModelHSB':/ – damian

+0

No. Se asignan al espacio RGB; usa el método RGB para ellos. De los documentos para 'colorWithHue: saturación: brillo: alfa:' ** La información de color representada por el objeto [el devuelto] está en el espacio de color RGB del dispositivo. ** –

1

Otra forma de convertirlos es dibujándolos en contextos y dejando que los gráficos centrales realicen la conversión por usted. Véase mi respuesta a esta pregunta:

Get RGB value from UIColor presets

+2

Guau, ¿de verdad? Eso parece una idea terrible. – damian

+0

@damian Sin dudas es feo, pero por lo que yo sé, es la única manera de que funcione de manera confiable, independientemente de cómo se haya creado el color original. Dado que a la pregunta original le preocupaba "no solo apoyar los espacios de color que existen ahora, sino todo lo que Apple podría agregar en el futuro", realmente no veo una buena alternativa. –

+0

ThinkDifferent (tm) – damian

2

Para los colores creados usando [UIColor colorWithRed:green:blue:alpha:], puede utilizar UIColor getRed:green:blue:alpha:, se describe en UIColor Class Reference. Es parte de iOS 5 y posterior.

Si el color se creó con colorWithWhite:alpha: puede utilizar el getWhite:alpha: en su 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, 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], distintos de dibujo a un mapa de bits temporal y detectarlos. Algunas de estas constantes de color son en realidad texturas; tu mejor opción es probablemente evitarlos.

Si usted planea 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 
+0

La pregunta específicamente pregunta cómo convertir colores entre espacios de color; si llama a este método, puede devolver 'NO', lo que significa que el receptor 'UIColor' está en un espacio de color diferente al espacio de color actual. Por ejemplo, 'BOOL success = [[UIColor lightGrayColor] getRed: & dummy green: & dummy blue: & dummy]' devuelve 'NO'. – damian

+0

Requiere un espacio de color compatible, no el mismo espacio de color. Algunos colores simplemente no son convertibles. Valdrá la pena con 'colorWithWhite: alpha:'. Parece que no has leído la pregunta completa y me has votado negativamente publicando la respuesta correcta. –

+0

No estoy seguro de qué significa espacio de color 'compatible', en ese caso. ¿Seguramente un espacio de color monocromático es "compatible" con un espacio de color RGB? He votado negativamente tu respuesta porque, en el caso de un color monocromo, el método que mencionas no solo no funciona, sino que sutilmente no funciona y no está claro por qué. – damian

1

en Swift 3 podemos utilizar directamente

let colorSpace = uiColor.cgColor.colorSpace 
let csModel = colorSpace.model 

para obtener el espacio de color y modelo de espacio de color de un UIColor.

Cuestiones relacionadas