如何将颜色从一种颜色空间转换为另一种颜色空间?

发布于 2024-07-27 01:01:24 字数 1550 浏览 7 评论 0 原文

是否有 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 也得到了处理。 但我想在这里编写一些代码,并且再也不会考虑它,这意味着不仅支持现在存在的色彩空间,还支持苹果将来可能添加的任何内容。 我运气不好吗?

Is there a Cocoa Touch way to convert colors from one color space to another?

At the end of this code:

UIColor *grey = [UIColor colorWithWhite: 0.5 alpha: 1.0];
CGColorRef greyRef = [grey CGColor];
int x = CGColorGetNumberOfComponents(greyRef);

...x is 2.

The reason I need this is I'm trying to copy colors to a list of color components for CGGradientCreateWithColorComponents, which needs all colors in a single colorspace. The problem is that grey is in the grayscale colorspace, rather than the RGB one. (The name escapes me at the moment, but it isn't important.)

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;
}

I know I can look for colors in the greyscale color space and convert them. But that only solves one case. From looking at this question, I think HSB is handled as well. But I'd like to write some code here and never think about it again, which means supporting not just the color spaces that are there now but anything Apple could conceivably add in the future. Am I out of luck?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

没有心的人 2024-08-03 01:01:24

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

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

然后您可以比较 colorSpaceModel< /code> 以及 CoreGraphics/CGColorSpace.h 中定义的常量。 UIColor 的 getRed:green:blue:alpha 适用于 kCGColorSpaceModelRGB,而 getWhite:alpha 适用于 kCGColorSpaceModelMonochrome

请注意,使用 colorWithHue:saturation:brightness:alpha: 创建的 UIColor 实际上位于 RGB 颜色空间中。

I'm not sure how to automatically convert them, but to identify different color spaces you can get the CGColorSpaceModel from the color's CGColorSpaceRef:

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

Then you can compare colorSpaceModel with the constants defined in CoreGraphics/CGColorSpace.h. UIColor's getRed:green:blue:alpha works for kCGColorSpaceModelRGB, whereas getWhite:alpha works for kCGColorSpaceModelMonochrome.

Note that a UIColor that was created with colorWithHue:saturation:brightness:alpha: will actually be in the RGB color space.

下雨或天晴 2024-08-03 01:01:24

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

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

UIColor 来获取颜色空间和颜色空间模型。

In swift 3 we can directly use

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

to get the color space and color space model from a UIColor.

虫児飞 2024-08-03 01:01:24

对于使用 [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

For colors created using [UIColor colorWithRed:green:blue:alpha:], you can use UIColor getRed:green:blue:alpha:, described in UIColor Class Reference. It's part of iOS 5 and later.

If the color was created with colorWithWhite:alpha: you can use the getWhite:alpha: instead, described in UIColor Class Reference.

To determine which color space is being used, you can use CGColorGetColorSpace([color colorSpace]). But it's probably easier to just check the result of the method call, then fail over to the next attempt. Something like this:

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
}

I don't know how to handle color constants such as [UIColor lightGrayColor], other than drawing them to a temporary bitmap and detecting them. Some of these color constants are actually textures; your best bet is probably to avoid them.

If you plan on doing this a lot, it's an appropriate use of a category:

@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
千仐 2024-08-03 01:01:24

使用 CGColor 方法:

func conversion(to _: CGColorSpace, Intent: CGColorRenderingIntent, options: CFDictionary?) -> CGColor?

我需要它来确保所有CGColor都位于CGColorSpaceCreateDeviceRGB颜色空间中。

cgColor.converted(至:CGColorSpaceCreateDeviceRGB(),意图:.defaultIntent,选项:nil)

https://developer.apple.com/documentation/coregraphics/cgcolor/1455493-converted

在此处输入图像描述

Use the CGColor method:

func converted(to _: CGColorSpace, intent: CGColorRenderingIntent, options: CFDictionary?) -> CGColor?

I needed it to make sure all the CGColor's were in the CGColorSpaceCreateDeviceRGB color space .

cgColor.converted(to: CGColorSpaceCreateDeviceRGB(), intent: .defaultIntent, options: nil)

https://developer.apple.com/documentation/coregraphics/cgcolor/1455493-converted

enter image description here

紫﹏色ふ单纯 2024-08-03 01:01:24

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

从 UIColor 预设中获取 RGB 值

Another way to convert these is by drawing them into contexts and letting core graphics do the conversion for you. See my answer to this question:

Get RGB value from UIColor presets

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文