2010-01-27 16 views
18

Sto cercando un modo per invertire i valori arbitrari di NSColor in fase di esecuzione e non sembra esserci alcun metodo incorporato per farlo.Esiste un metodo convenzionale per invertire i valori NSColor?

userò una categoria di estendere NSColor come segue:

NSColor * invertedColor = [someOtherColor inverted]; 

Ecco il metodo prototipo di categoria che sto usando:

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

chiunque può riempire gli spazi vuoti? Questo non deve essere perfetto, ma mi piacerebbe che avesse un senso. cioè .:

  1. [[[NSColor someColor] inverted] inverted] determinerebbe un colore molto vicino al colore originale

  2. [[NSColor whiteColor] inverted] sarebbe molto vicino a [NSColor blackColor]

  3. colori invertiti sarebbe su lati opposti del color wheel. (Rosso & verde, giallo & viola, ecc)

Il valore alfa deve rimanere lo stesso dell'originale NSColor. Sto solo cercando di invertire il colore, non la trasparenza.

UPDATE 3: (! Ora a colori)

Si scopre che utilizzando una (un colore con una tonalità di 180 ° di distanza dalla tonalità originale) complementary color non è abbastanza, in quanto bianco e il nero non ha davvero un valore di tonalità. Partendo dalla risposta fornita da phoebus, questo è ciò che è venuta:

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 tonalità è ancora ruotata di 180 °, ma anche invertire la componente luminosità in modo che i colori molto scuri diventano molto luminoso (e viceversa). Questo si occupa dei casi in bianco e nero, ma inverte quasi ogni colore in nero (che viola la mia regola di doppia inversione). Ecco i risultati:

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

Ora, Peter Hosey's approach è molto più semplice, e produce risultati migliori:

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

risposta

21

Semplice: i componenti sono tutti 0-1, quindi sottrarre ciascun componente da 1 per ottenere il valore del complemento.

Esempi:

  • Red = 1, 0, 0; complemento = 0, 1, 1 = cyan
  • Giallo = 1, 1, 0; complemento = 0, 0, 1 = blu
  • Bianco = 1, 1, 1; complemento = 0, 0, 0 = nero
  • arancione intenso = 1, 0,25, 0; complemento = 0, 0,75, 1 = cielo blu

Come si può intuire, questa operazione è simmetrica. Invertendo l'inverso si ottiene esattamente il colore con cui hai iniziato.

+0

Suvato per essere diretto su di esso :) – phoebus

+0

Nota: per grigio = 0,5, 0,5, 0,5; complemento è se stesso. – Pang

3

Da ciò che si descrive, suona come ciò che realmente voglio è una funzione per trovare il complemento di un colore, non il suo inverso. Invertire significa qualcosa di diverso in questo contesto.

Here's a StackOverflow question regarding complements in JavaScript. Forse parte del codice è adattabile?

Here è alcune informazioni interessanti e potenzialmente utili sui vari modi in cui il colore può essere lavorato con gli spazi colore Cocoa.Da come appare, se è possibile utilizzare lo spazio colore HSV, è possibile trovare il complemento di un colore semplicemente prendendo hue > 179 ? hue -= 180 : hue = += 180, poiché le tonalità sono definite attorno alla ruota dei colori in un cerchio completo.

+0

Questo codice Java sembra essere molto promettente. Gli darò un vortice. –

+0

E grazie per il punto sui colori complementari rispetto ai colori invertiti. Lo aggiungerò alla domanda. –

1

Ecco alcune oneliner con setter personalizzato (alfa non è invertita!):

-(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

potresti prendere in considerazione l'utilizzo di const CGFloat * cc = CGColorGetComponents (originalColor.CGColor); ritorno [Colore colore UIC: (1-cc [0]) verde: (1-cc [1]) blu: (1-cc [2]) alfa: CGColorGetAlpha (originalColor.CGColor)]; (perché chiamare una funzione 3 volte per ottenere lo stesso risultato?) – unsynchronized