如何将颜色从一种颜色空间转换为另一种颜色空间?
-
11-09-2019 - |
题
是否有 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也处理好了。但我想在这里编写一些代码,并且再也不会考虑它,这意味着不仅支持现在存在的色彩空间,还支持苹果将来可能添加的任何内容。我运气不好吗?
解决方案
我不知道如何自动转换他们,而是要找出不同的色彩空间,你可以得到色彩的CGColorSpaceModel
的CGColorSpaceRef
:
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
颜色空间和颜色空间模型。
要转换这些另一种方式是把他们拉入情境,让核心显卡为你做转换。见我回答这个问题: