是否有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也得到了处理。但是我想在这里编写一些代码而不再考虑它,这意味着不仅要支持现在的色彩空间,还要支持苹果未来可以想象的任何东西。我运气不好吗?
答案 0 :(得分:7)
我不确定如何自动转换它们,但为了识别不同的颜色空间,您可以从颜色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颜色空间中。
答案 1 :(得分:2)
对于使用[UIColor colorWithRed:green:blue:alpha:]
创建的颜色,您可以使用UIColor Class Reference中描述的UIColor getRed:green:blue:alpha:
。它是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
答案 2 :(得分:2)
在swift 3中我们可以直接使用
let colorSpace = uiColor.cgColor.colorSpace
let csModel = colorSpace.model
从UIColor
获取色彩空间和色彩空间模型。
答案 3 :(得分:1)
转换这些内容的另一种方法是将它们绘制到上下文中,让核心图形为您进行转换。看看我对这个问题的回答:
答案 4 :(得分:0)
使用CGColor方法:
func converted(to _: CGColorSpace, intent: CGColorRenderingIntent, options: CFDictionary?) -> CGColor?
我需要它来确保所有CGColor
都在CGColorSpaceCreateDeviceRGB
颜色空间中。
cgColor.converted(to: CGColorSpaceCreateDeviceRGB(), intent: .defaultIntent, options: nil)
https://developer.apple.com/documentation/coregraphics/cgcolor/1455493-converted