2009-07-08 12 views
17

Czy istnieje sposób dotykowy Cocoa Touch do zamiany kolorów z jednej przestrzeni kolorów na drugą?Jak przekonwertować kolory z jednej przestrzeni kolorów na drugą?

Pod koniec tego kodu:

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

... x jest 2.

Powodem muszę to staram się kopiować kolory na liście składników koloru dla CGGradientCreateWithColorComponents , który potrzebuje wszystkich kolorów w jednej przestrzeni kolorów. Problem polega na tym, że kolor szary znajduje się w przestrzeni kolorów w skali szarości, a nie w kolorze RGB. (Nazwa ucieczki mnie w tej chwili, ale to nie jest ważne.)

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

wiem, że mogę spojrzeć na kolory w przestrzeni kolorów szarości i konwertować je. Ale to rozwiązuje tylko jeden przypadek. Patrząc na at this question, myślę, że HSB również jest obsługiwany. Ale chciałbym tutaj napisać jakiś kod i nigdy więcej o tym nie myśleć, co oznacza wspieranie nie tylko przestrzeni kolorów, które teraz istnieją, ale wszystkiego, co Apple mogłoby dodać w przyszłości. Czy mam pecha?

Odpowiedz

7

nie jestem pewien, jak automatycznie konwertować je, ale zidentyfikować różne przestrzenie kolorów można uzyskać CGColorSpaceModel od koloru na CGColorSpaceRef:

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

Następnie można porównać colorSpaceModel ze stałych zdefiniowanych w CoreGraphics/CGColorSpace.h. UIColor's getRed:green:blue:alpha działa dla kCGColorSpaceModelRGB, natomiast getWhite:alpha działa dla kCGColorSpaceModelMonochrome.

Należy pamiętać, że UIColor utworzony za pomocą colorWithHue:saturation:brightness:alpha: znajdzie się w przestrzeni kolorów RGB.

+0

To całkiem niezła odpowiedź, choć warto wspomnieć, że kolory HSB są umieszczane w przestrzeni kolorów RGB. Tak więc, jest to całkowicie poprawne nazywanie 'getRed: green: blue: alpha:' na nich. –

+0

Hmm, nie ma "kCGColorSpaceModelHSB":/ – damian

+0

Nie. Są mapowani do przestrzeni RGB; użyj dla nich metody RGB. Z dokumentów dla 'colorWithHue: saturation: brightness: alpha:' ** Informacje o kolorach reprezentowane przez [zwrócony] obiekt znajduje się w przestrzeni kolorów urządzenia RGB. ** –

1

Innym sposobem na ich konwersję jest narysowanie ich w kontekstach i umożliwienie podstawowej grafiki konwersji za Ciebie. Zobacz moją odpowiedź na to pytanie:

Get RGB value from UIColor presets

+2

Wow, naprawdę? To wygląda na okropny pomysł. – damian

+0

@damian Bez wątpienia jest brzydka, ale z tego, co wiem, jest to jedyny sposób, który działa niezawodnie niezależnie od tego, jak powstał oryginalny kolor. Biorąc pod uwagę, że pierwotne pytanie było zaniepokojone "wsparciem nie tylko przestrzeni kolorów, które teraz istnieją, ale czymkolwiek, co Apple mógłby dodać w przyszłości", nie widzę dobrej alternatywy. –

+0

ThinkDifferent (tm) – damian

2

Dla kolorów stworzony przy użyciu [UIColor colorWithRed:green:blue:alpha:] można użyć UIColor getRed:green:blue:alpha:, opisaną w UIColor Class Reference. Jest częścią systemu iOS 5 i nowszych.

Jeśli kolor został utworzony za pomocą colorWithWhite:alpha:, można użyć getWhite:alpha: zamiast tego, opisanego w UIColor Class Reference.

Aby ustalić, która przestrzeń kolorów jest używana, można użyć CGColorGetColorSpace([color colorSpace]). Ale prawdopodobnie łatwiej jest po prostu sprawdzić wynik wywołania metody, a następnie przejść do następnej próby. Coś takiego:

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 
} 

nie wiem jak obsługiwać kolorów stałych takich jak [UIColor lightGrayColor], inne niż rysunek je do tymczasowego bitmapy i ich wykrywania. Niektóre z tych stałych kolorów są w rzeczywistości teksturami; Twoim najlepszym rozwiązaniem jest prawdopodobnie ich uniknąć.

Jeśli masz zamiar robić to dużo, to jest odpowiednie wykorzystanie kategoriach:

@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

Pytanie w szczególności pyta, jak konwertować kolory między przestrzeniami kolorów; jeśli wywołasz tę metodę, może zwrócić 'NO', co oznacza, że ​​odbiornik' UIColor' znajduje się w innej przestrzeni kolorów niż obecna przestrzeń kolorów. Na przykład: 'BOOL success = [[UIColor lightGrayColor] getRed: & dummy green: & dummy blue: & dummy]' zwraca 'NO'. – damian

+0

Wymaga zgodnej przestrzeni kolorów, a nie tej samej przestrzeni kolorów. Niektóre kolory po prostu nie są wymienialne. Będzie warta z 'colorWithWhite: alpha:'. Wygląda na to, że nie przeczytałeś pełnego pytania, a mnie zarzuciłeś, że wysłałem poprawną odpowiedź. –

+0

Nie jestem pewien, co oznacza "zgodna" przestrzeń kolorów w tym przypadku. Z pewnością monochromatyczna przestrzeń kolorów jest "zgodna" z przestrzenią kolorów RGB? Zignorowałem twoją odpowiedź, ponieważ w przypadku koloru monochromatycznego wspomniana metoda nie tylko nie działa, ale też nie działa i nie jest jasne, dlaczego. – damian

1

w Swift 3 możemy bezpośrednio korzystać

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

uzyskać przestrzeń barw i model przestrzeni koloru z UIColor.

Powiązane problemy