是否有 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;
}

我知道我可以在灰度颜色空间中查找颜色并转换它们。但这只能解决一种情况。从看 在这个问题上, ,我觉得HSB也处理好了。但我想在这里编写一些代码,并且再也不会考虑它,这意味着不仅支持现在存在的色彩空间,还支持苹果将来可能添加的任何内容。我运气不好吗?

有帮助吗?

解决方案

我不知道如何自动转换他们,而是要找出不同的色彩空间,你可以得到色彩的CGColorSpaceModelCGColorSpaceRef

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

然后,可以在colorSpaceModel定义的常量比较CoreGraphics/CGColorSpace.h。的UIColor的getRed:green:blue:alpha工程kCGColorSpaceModelRGB,而getWhite:alpha作品kCGColorSpaceModelMonochrome

请注意,将其用UIColor创建colorWithHue:saturation:brightness:alpha:实际上将在RGB颜色空间。

其他提示

对于使用创建的颜色 [UIColor colorWithRed:green:blue:alpha:], , 您可以使用 UIColor getRed:green:blue:alpha:, ,描述于 UIColor 类参考. 。它是 iOS 5 及更高版本的一部分。

如果颜色是用创建的 colorWithWhite:alpha: 你可以使用 getWhite:alpha: 相反,描述于 UIColor 类参考.

要确定正在使用哪个色彩空间,您可以使用 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

在迅速3我们可以直接使用

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

得到一个UIColor颜色空间和颜色空间模型。

要转换这些另一种方式是把他们拉入情境,让核心显卡为你做转换。见我回答这个问题:

获得从预设的UIColor RGB值

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top