2009-07-08 8 views
17

Gibt es einen Cocoa Touch-Weg, um Farben von einem Farbraum in einen anderen zu konvertieren?Wie konvertiert man Farben von einem Farbraum in einen anderen?

Am Ende dieses Codes:

UIColor *grey = [UIColor colorWithWhite: 0.5 alpha: 1.0]; 
CGColorRef greyRef = [grey CGColor]; 
int x = CGColorGetNumberOfComponents(greyRef); 

... x ist 2.

Der Grund, warum ich brauche das ist Ich versuche Farben auf eine Liste von Farbkomponenten für CGGradientCreateWithColorComponents zu kopieren , die alle Farben in einem einzigen Farbraum benötigt. Das Problem besteht darin, dass Grau im Graustufenfarbraum liegt und nicht im RGB-Farbraum. (Der Name entgeht mir im Moment, aber es ist nicht wichtig.)

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

Ich weiß, dass ich für Farben in der Graustufen-Farbraum aussehen kann und sie konvertieren. Aber das löst nur einen Fall. Von der Suche at this question denke ich, dass HSB auch gehandhabt wird. Aber ich würde hier gerne etwas Code schreiben und nie wieder darüber nachdenken, was bedeutet, dass ich nicht nur die Farbräume unterstütze, die es jetzt gibt, sondern alles, was Apple in Zukunft vielleicht hinzufügen könnte. Habe ich kein Glück?

Antwort

7

Ich bin nicht sicher, wie man sie automatisch konvertieren, aber unterschiedliche Farbräume identifizieren Sie die CGColorSpaceModel bekommen von der Farbe der CGColorSpaceRef:

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

Dann können Sie in CoreGraphics/CGColorSpace.h definiert colorSpaceModel mit den Konstanten vergleichen. UIColor getRed:green:blue:alpha arbeitet für kCGColorSpaceModelRGB, während getWhite:alpha für kCGColorSpaceModelMonochrome arbeitet.

Beachten Sie, dass ein UIColor, der mit colorWithHue:saturation:brightness:alpha: erstellt wurde, tatsächlich im RGB-Farbraum sein wird.

+0

Dies ist eine ziemlich gute Antwort, obwohl Sie vielleicht erwähnen möchten, dass HSB-Farben in den RGB-Farbraum gelegt werden. Daher ist es absolut richtig, 'getRed: grün: blau: alpha:' auf ihnen zu nennen. –

+0

Hmm, da scheint kein 'kCGColorSpaceModelHSB' zu sein:/ – damian

+0

Nein. Sie werden dem RGB-Raum zugeordnet; Verwenden Sie die RGB-Methode für sie. Aus der Dokumentation für 'colorWithHue: saturation: Helligkeit: alpha:' ** Die Farbinformation von [dem zurückgegebenen] Objekt ist im RGB-Farbraum des Geräts. ** –

1

Eine andere Möglichkeit, diese zu konvertieren, besteht darin, sie in Kontexte zu zeichnen und die Kerngrafiken für Sie konvertieren zu lassen. Siehe meine Antwort auf diese Frage:

Get RGB value from UIColor presets

+2

Wow, wirklich? Das scheint eine schreckliche Idee zu sein. – damian

+0

@damian Keine Frage, es ist hässlich, aber soweit ich weiß, ist es der einzige Weg, der zuverlässig funktioniert, unabhängig davon, wie die ursprüngliche Farbe erstellt wurde. Angesichts der Tatsache, dass die ursprüngliche Frage beunruhigt war, "nicht nur die Farbräume zu unterstützen, die es jetzt gibt, sondern alles, was Apple in Zukunft vielleicht hinzufügen könnte", sehe ich keine gute Alternative. –

+0

ThinkDifferent (tm) – damian

2

Für Farben mit [UIColor colorWithRed:green:blue:alpha:] erstellt haben, können Sie UIColor getRed:green:blue:alpha:, beschrieben in UIColor Class Reference verwenden. Es ist Teil von iOS 5 und höher. Wenn die Farbe mit colorWithWhite:alpha: erstellt wurde, können Sie stattdessen die getWhite:alpha: verwenden, die in UIColor Class Reference beschrieben ist.

Um festzustellen, welcher Farbraum verwendet wird, können Sie CGColorGetColorSpace([color colorSpace]) verwenden. Es ist jedoch wahrscheinlich einfacher, das Ergebnis des Methodenaufrufs zu überprüfen und dann zum nächsten Versuch überzugehen. Etwas wie folgt aus:

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 
} 

Ich weiß nicht, wie Farbkonstanten wie [UIColor lightGrayColor], anders als sie in eine temporäre Bitmap zeichnen und Erkennen sie zu handhaben. Einige dieser Farbkonstanten sind tatsächlich Texturen; Ihre beste Wette ist wahrscheinlich, sie zu vermeiden.

Wenn Sie tun dies viel zu planen, ist es eine angemessene Verwendung einer Kategorie:

@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

Die Frage fragt speziell, wie Farben zwischen Farbräumen konvertiert werden; Wenn Sie diese Methode aufrufen, wird möglicherweise "NO" zurückgegeben, dh der Empfänger "UIColor" befindet sich in einem anderen Farbraum als der aktuelle Farbraum. Beispiel: 'BOOL success = [[UIColor lightGrayColor] getRed: & dummy grün: & dummy blau: & dummy]' gibt 'NO' zurück. – damian

+0

Es erfordert einen kompatiblen Farbraum, nicht den gleichen Farbraum. Manche Farben sind einfach nicht konvertierbar. Es lohnt sich mit 'colorWithWhite: alpha:'. Sie scheinen die vollständige Frage nicht gelesen zu haben, und Sie haben mich abgelehnt, die richtige Antwort zu posten. –

+0

Ich bin mir nicht sicher, was "kompatibler" Farbraum in diesem Fall bedeutet. Sicherlich ist ein monochromer Farbraum mit einem RGB-Farbraum "kompatibel"? Ich habe Ihre Antwort abgelehnt, weil im Fall einer monochromen Farbe die von Ihnen genannte Methode nicht nur nicht funktioniert, sondern subtil nicht funktioniert und es nicht klar ist, warum. – damian

1

In swift 3 können wir direkt

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

verwenden Sie den Farbraum und Farbraummodell von einem UIColor zu bekommen.

Verwandte Themen