2010-01-27 13 views
18

Estoy buscando una manera de invertir valores arbitrarios NSColor en tiempo de ejecución, y no parece haber ningún método incorporado para hacerlo.¿Existe un método convencional para invertir los valores NSColor?

Me va a utilizar una categoría para extender NSColor de la siguiente manera:

NSColor * invertedColor = [someOtherColor inverted]; 

Aquí está la categoría de prototipos método que estoy usando:

@implementation NSColor (MyCategories) 
- (NSColor *)inverted 
{ 
    NSColor * original = [self colorUsingColorSpaceName: 
         NSCalibratedRGBColorSpace]; 
    return ...? 
} 
@end 

¿Alguien puede llenar los espacios en blanco? Esto no tiene por qué ser perfecto, pero me gustaría que tenga sentido. es decir .:

  1. [[[NSColor someColor] inverted] inverted] daría como resultado un color muy parecido al color original de

  2. [[NSColor whiteColor] inverted] sería muy cerca de [NSColor blackColor]

  3. colores invertidos sería en lados opuestos de la color wheel. (Rojo & verde, amarillo & violeta, etc.)

El valor alfa debe seguir siendo el mismo que el original NSColor. Solo estoy buscando invertir el color, no la transparencia.

ACTUALIZACIÓN 3: (! Ahora en color)

Resulta que el uso de un (un color con una tonalidad 180 ° fuera de la tonalidad original de) complementary color no es suficiente, puesto que el blanco y negro realmente no tiene un valor de tono. A partir de la respuesta proporcionada por phoebus, esto es lo que ocurrió:

CGFloat hue = [original hueComponent]; 
if (hue >= 0.5) { hue -= 0.5; } else { hue += 0.5; } 
return [NSColor colorWithCalibratedHue:hue 
          saturation:[original saturationComponent] 
          brightness:(1.0 - [original brightnessComponent]) 
           alpha:[original alphaComponent]]; 

La tonalidad aún se gira 180 °, pero también invertir la componente de brillo para que los colores muy oscuros se vuelven muy brillante (y viceversa) Esto se ocupa de los casos en blanco y negro, pero invierte casi todos los colores en negro (lo que infringe mi regla de doble inversión). Aquí están los resultados:

color swatch #1 http://img29.imageshack.us/img29/8548/invert1.jpg

Ahora, Peter Hosey's approach es mucho más simple, y produce mejores resultados:

return [NSColor colorWithCalibratedRed:(1.0 - [original redComponent]) 
           green:(1.0 - [original greenComponent]) 
            blue:(1.0 - [original blueComponent]) 
           alpha:[original alphaComponent]]; 

color swatch #2 http://img29.imageshack.us/img29/1513/invert2.jpg

Respuesta

21

Simple: Todos los componentes son 0-1, restar cada componente de 1 para obtener el valor del complemento.

Ejemplos:

  • Rojo = 1, 0, 0; complemento = 0, 1, 1 = cian
  • Amarillo = 1, 1, 0; complemento = 0, 0, 1 = azul
  • Blanco = 1, 1, 1; complemento = 0, 0, 0 = negro
  • Naranja intenso = 1, 0.25, 0; complemento = 0, 0.75, 1 = azul cielo

Como puede adivinar, se trata de una operación simétrica. Al invertir el inverso obtendrá exactamente el color con el que comenzó.

+0

Votado positivamente por ser simple :) – phoebus

+0

Nota: Gris = 0.5, 0.5, 0.5; el complemento es en sí mismo. – Pang

3

De lo que describes, parece que lo que realmente querer es una función para encontrar el complemento de un color, no su inverso. Invertir significa algo diferente en este contexto.

Here's a StackOverflow question regarding complements in JavaScript. Tal vez parte del código es adaptable?

Here es una información interesante y potencialmente útil sobre las diversas formas en que se puede trabajar con el color en los espacios de color Cocoa.De lo que parece aquí, si puede usar el espacio de color HSV, entonces puede encontrar el complemento de un color simplemente tomando hue > 179 ? hue -= 180 : hue = += 180, ya que los matices se definen alrededor de la rueda de colores en un círculo completo.

+0

Ese código Java parece prometedor. Voy a darle un giro. –

+0

Y gracias por el punto acerca de colores complementarios vs colores invertidos. Añadiré eso a la pregunta. –

1

Aquí es un poco de oneliner con colocador personalizado (alfa no se invierte!):

-(void)setReverseFontColor:(UIColor *)reverseFontColor { 
    _reverseFontColor = [AppSingleStyle reversedColorFromOriginal:reverseFontColor]; 
} 

+(UIColor*)reversedColorFromOriginal:(UIColor*)originalColor { 
    return [UIColor colorWithRed:(1-CGColorGetComponents(originalColor.CGColor)[0]) green:(1-CGColorGetComponents(originalColor.CGColor)[1]) blue:(1-CGColorGetComponents(originalColor.CGColor)[2]) alpha:CGColorGetAlpha(originalColor.CGColor)]; 
} 
+0

es posible que desee considerar el uso de const CGFloat * cc = CGColorGetComponents (originalColor.CGColor); return [UIColor colorWithRed: (1-cc [0]) verde: (1-cc [1]) azul: (1-cc [2]) alpha: CGColorGetAlpha (originalColor.CGColor)]; (¿por qué llamar a una función 3 veces para obtener el mismo resultado?) – unsynchronized

Cuestiones relacionadas