20

是否有一种 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 也得到了处理。但我想在这里写一些代码,以后再也不去想它了,这意味着不仅支持现在存在的色彩空间,还支持苹果未来可能添加的任何东西。我运气不好?

4

5 回答 5

8

我不确定如何自动转换它们,但要识别不同的颜色空间,您可以CGColorSpaceModel从颜色中获取CGColorSpaceRef

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

然后你可以colorSpaceModel与定义的常量进行比较CoreGraphics/CGColorSpace.h。UIColorgetRed:green:blue:alpha适用于kCGColorSpaceModelRGB,而getWhite:alpha适用于kCGColorSpaceModelMonochrome.

请注意,UIColor创建的acolorWithHue:saturation:brightness:alpha:实际上将在 RGB 颜色空间中。

于 2013-06-07T10:26:16.900 回答
4

在swift 3中我们可以直接使用

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

从 a 中获取颜色空间和颜色空间模型UIColor

于 2016-08-24T03:31:59.937 回答
2

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

如果颜色是用你创建的,colorWithWhite:alpha:你可以使用UIColor Class ReferencegetWhite:alpha:中描述的。

要确定正在使用哪个色彩空间,您可以使用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
于 2013-05-09T02:49:51.163 回答
1

另一种转换它们的方法是将它们绘制到上下文中并让核心图形为您进行转换。看我对这个问题的回答:

从 UIColor 预设中获取 RGB 值

于 2011-01-15T15:23:34.730 回答
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

在此处输入图像描述

于 2020-02-21T21:09:14.017 回答