2010-01-27 22 views
18

Ich bin auf der Suche nach einer Möglichkeit, um beliebige NSColor Werte zur Laufzeit zu invertieren, und es scheint keine eingebaute Methode dafür zu sein.Gibt es eine konventionelle Methode zur Invertierung von NSColor-Werten?

Ich werde eine Kategorie verwenden NSColor zu verlängern, wie folgt:

NSColor * invertedColor = [someOtherColor inverted]; 

ist die Kategorie Methode Prototyp, ich verwende:

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

Kann jemand in die Lücken füllen? Das muss nicht perfekt sein, aber ich möchte, dass es einen Sinn ergibt. d.h .:

  1. [[[NSColor someColor] inverted] inverted] würde eine Farbe ganz in der Nähe der ursprünglichen Farbe

  2. [[NSColor whiteColor] inverted] wäre ganz in der Nähe [NSColor blackColor]

  3. Inverted Farben auf gegenüberliegenden Seiten der color wheel wäre. (Rot & grün, gelb & violett, usw.)

Der Alpha-Wert die gleiche wie das Original NSColor bleiben sollte. Ich versuche nur, die Farbe zu invertieren, nicht die Transparenz.

UPDATE 3: (! Jetzt in Farbe)

Es stellt sich heraus, dass eine complementary color (aus dem ursprünglichen Farbton mit einem Farbton 180 ° weg eine Farbe) verwendet, ist nicht genug, da weiß und Schwarz hat eigentlich keinen Farbtonwert. Ausgehend von der Antwort von phoebus vorgesehen ist, ist es das, was ich kam mit:

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]]; 

Der Farbton noch um 180 ° gedreht wird, aber ich habe auch die Helligkeitskomponente invertieren, so dass sehr dunkle Farben sehr hell worden (und umgekehrt). Dies kümmert sich um die Schwarz-Weiß-Fälle, aber es invertiert fast jede Farbe in Schwarz (was gegen meine Doppelinversionsregel verstößt). Hier sind die Ergebnisse:

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

Nun Peter Hosey's approach ist viel einfacher, und es produziert bessere Ergebnisse:

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

Antwort

21

Einfach: Die Komponenten sind alle 0-1, also subtrahieren Sie jede Komponente von 1, um den Wert des Komplements zu erhalten.

Beispiele:

  • Rot = 1, 0, 0; Komplement = 0, 1, 1 = cyan
  • Gelb = 1, 1, 0; Komplement = 0, 0, 1 = Blau
  • Weiß = 1, 1, 1; Komplement = 0, 0, 0 = schwarz
  • Deep Orange = 1, 0,25, 0; ergänzen = 0, 0,75, 1 = himmelblau

Wie Sie sich vorstellen können, ist dies ein symmetrischer Betrieb. Invertieren invertiert erhalten Sie genau die Farbe, mit der Sie begonnen haben. Hier

+0

Upvoted für einfach zu sein :) – phoebus

+0

Hinweis: Für grau = 0,5, 0,5, 0,5; Komplement ist es selbst. – Pang

3

Von dem, was Sie beschreiben, klingt es wie das, was Sie wirklich want ist eine Funktion, um das Komplement einer Farbe zu finden, nicht umgekehrt. Invertieren bedeutet in diesem Zusammenhang etwas anderes.

Here's a StackOverflow question regarding complements in JavaScript. Vielleicht ist ein Teil des Codes anpassungsfähig?

Here ist eine interessante und potentiell nützliche Information über die verschiedenen Möglichkeiten der Farbverarbeitung in Cocoa-Farbräumen.So wie es hier aussieht, wenn Sie den HSV-Farbraum verwenden können, dann könnte das Komplement einer Farbe gefunden werden, indem einfach hue > 179 ? hue -= 180 : hue = += 180 genommen wird, da die Farbtöne um das Farbrad in einem vollen Kreis definiert sind.

+0

Der Java-Code sieht vielversprechend aus. Ich werde es drehen. –

+0

Und danke für den Punkt über Komplementärfarben vs umgekehrte Farben. Ich füge das zur Frage hinzu. –

1

sind einige oneliner mit benutzerdefinierten Setter (alpha nicht umgekehrt!):

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

möchten Sie möglicherweise const CGFloat verwenden * cc = CGColorGetComponents (originalColor.CGColor); zurück [UIColor colorWithRed: (1-cc [0]) grün: (1-cc [1]) blau: (1-cc [2]) alpha: CGColorGetAlpha (originalColor.CGColor)]; (Warum eine Funktion dreimal aufrufen, um das gleiche Ergebnis zu erhalten?) – unsynchronized