2009-07-08 57 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的色彩空间和色彩空间模型。

相关问题