2009-07-08 60 views
17

是否有一種Cocoa Touch方式將顏色從一種顏色空間轉換爲另一種顏色空間?如何將顏色從一個顏色空間轉換爲另一個顏色空間?

這段代碼的末尾:

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

... x是2

我之所以需要這個是我想要的顏色複製爲CGGradientCreateWithColorComponents顏色成分的列表,它需要一個色彩空間中的所有顏色。問題是灰色是在灰度色彩空間中,而不是RGB色彩空間。 (名字我想不起來了的那一刻,但它並不重要。)

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

我知道我可以找顏色灰度色彩空間,並將其轉換。但那隻能解決一個案例。從看at this question,我認爲HSB也是如此。但是我想在這裏寫一些代碼,而不再考慮它,這意味着不僅支持現在存在的色彩空間,而且支持Apple未來可能會增加的任何色彩空間。我運氣不好嗎?

回答

7

我不知道如何自動將它們轉換,而是確定不同的色彩空間,你可以得到CGColorSpaceModel從顏色的CGColorSpaceRef

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

然後你就可以比較colorSpaceModelCoreGraphics/CGColorSpace.h定義的常量。 UIColor的getRed:green:blue:alpha適用於kCGColorSpaceModelRGB,而getWhite:alpha適用於kCGColorSpaceModelMonochrome

請注意,使用colorWithHue:saturation:brightness:alpha:創建的UIColor實際上將在RGB顏色空間中。

1

轉換這些的另一種方法是將它們繪製到上下文中並讓核心圖形爲您進行轉換。見我回答這個問題:

Get RGB value from UIColor presets

+2

哇,真的嗎?這似乎是一個可怕的想法。 – damian 2013-06-07 10:34:55

+0

@ damian毫無疑問這是醜陋的,但據我所知,它是唯一能可靠工作的方式,無論原始顏色是如何創建的。鑑於最初的問題是擔心「不僅支持現在存在的色彩空間,而且蘋果未來可能會增加色彩空間」我並不認爲有一個好的選擇。 – 2013-06-07 23:51:11

+0

ThinkDifferent(tm) – damian 2013-06-08 06:34:50

2

對於顏色使用[UIColor colorWithRed:green:blue:alpha:]創建的,你可以使用UIColor getRed:green:blue:alpha:,在UIColor Class Reference描述。它是iOS 5及更高版本的一部分。

如果顏色是使用colorWithWhite:alpha:創建的,則可以使用getWhite:alpha:代替,如UIColor Class Reference中所述。

要確定正在使用哪個色彩空間,可以使用CGColorGetColorSpace([color colorSpace])。但是,檢查方法調用的結果可能更容易,然後故障轉移到下一次嘗試。事情是這樣的:

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 
} 

我不知道如何處理顏色常量如[UIColor lightGrayColor],比他們繪製到一個臨時位圖和檢測他們的其他。其中一些顏色常量實際上是紋理;你最好的選擇是避免它們。

如果你打算這樣做了很多,這是一個合適的使用類別:

@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 
1

在SWIFT 3我們可以直接使用

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

獲得從UIColor的色彩空間和色彩空間模型。

相關問題