给定大量 RGB 值,我想将它们与标准 UIColor 关联并配对。例如,(255,0,0) 是“常见的”红色。我也想将 (254,85,44) 和 (193,0,1) 之类的值配对并标记为“红色”。只要它们接近红色,我想说它是“红色”。实现这一目标的最佳方法是什么?我尝试测试亮度,甚至将其与通用公式的标准 (255,0,0) 进行比较,但没有成功。有什么建议么?
4 回答
您最好的选择是将 RBG 值转换为 HSL 或 HSV(有时称为 HSB)。然后检查色调值。如果色调出现在 0-15 或 340-360 的范围内(调整这些范围以适合您自己对“红色”的定义),那么您可以认为颜色是红色的。当然,其中一些几乎是黑色或白色的,您可能还想限制亮度或亮度值。
int red = ... // your red value (0 - 255)
int green = ... // your green value (0 - 255)
int blue = ... // your blue value (0 - 255)
UIColor *RGBColor = [UIColor colorWithRed:red / 255.0 green:green / 255.0 blue:blue / 255.0 alpha:1.0];
CGFloat hue, saturation, brightness;
if ([RGBColor getHue:&hue saturation:&saturation brightness:&brightness alpha:nil]) {
// Replace 15 and 240 with values you consider to be "red"
if (hue < 15/360.0 || hue > 240/360.0) {
// this can be considered "red"
}
} else {
// oops - can't convert
}
与@frowing 所说的基本相同,但我还有一些#defined 宏可以让我的生活更轻松:
#define RGB(R, G, B) ([UIColor colorWithRed:R/255.0f green:G/255.0f blue:B/255.0f alpha:1.0f])
#define G(W) ([UIColor colorWithWhite:W/255.0f alpha:1.0f])
#define RGBA(R, G, B, A) ([UIColor colorWithRed:R/255.0f green:G/255.0f blue:B/255.0f alpha:A])
#define GA(W, A) ([UIColor colorWithWhite:W/255.0f alpha:A])
#define RANDCOLOR ([UIColor colorWithHue:fmodf(((float)arc4random()/0x100000000)+0.618033988749895f, 1.0f) saturation:0.75f brightness:0.95f alpha:1.0f]) // From http://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/
#define RANDCOLOR_ALPHA(A) ([UIColor colorWithHue:fmodf(((float)arc4random()/0x100000000)+0.618033988749895f, 1.0f) saturation:0.75f brightness:0.95f alpha:A]) // From http://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/
- RGB(R, G, B) 用于简单的 RGB 到 UIColor 的转换
- G(W) 用于灰色颜色空间中的简单 UIColor
- RGBA(R, G, B, A) 与 RGB() 相同,但具有指定的 Alpha 通道
- GA(W, A) 与 G() 相同,但具有指定的 Alpha 通道
- RANDCOLOR() 只是一种随机颜色(有关为什么这不仅仅是每个 RGB 值的随机数的更多详细信息,请参见链接)
- RANDCOLOR_ALPHA(A) 与 RANDCOLOR() 相同,但具有指定的 alpha 通道
编辑1:我读错了你的问题。我的错。
我将从一组您想用作标签的定义颜色开始。例如:
#define COLOR_RED RGB(193.0f, 0.0f, 1.0f)
然后我会使用 rgb 到 rgb 计算来计算颜色在 3d 空间中的距离。所以像:
const float* rgb1 = CGColorGetComponents( color1.CGColor );
const float* rgb2 = CGColorGetComponents( color2.CGColor );
double diff = pow(pow(rgb2[0] - rgb1[0], 2) + pow(rgb2[1] - rgb1[1], 2) + pow(rgb2[2] - rgb1[2], 2), 0.5);
为结果选择一个阈值,将其写入一个函数,遍历您的标签(或标签数组和相应的 UIColors),并返回差异低于某个阈值的标签。
需要注意的一点是,假设您的颜色都在 RGB 颜色空间中。只有当您的颜色在 RGB 颜色空间中时,CGColorGetComponents 才会返回 RGB。灰度颜色将返回不同的值(以及 rgb1 和 rgb2 的不同大小的数组)。
编辑 2:好的,我从旧教科书中做了一些研究,您想要使用的颜色数据称为 L*a*b 颜色空间。
来自http://en.wikipedia.org/wiki/Lab_color_space
与 RGB 和 CMYK 颜色模型不同,Lab 颜色旨在接近人类视觉。
我首先将 RGB 值转换为 L*a*b 空间,然后在我上面为 rgb 值概述的相同 3d 空间距离计算中使用 l,a,b 值。这被称为 CIE76 算法(它不是最好的,但可能是更容易实现的算法之一……请参阅下面的注释)。该数值差异值应该让您接近了解两种颜色与人眼的相似程度。然后根据一些测试,我会选择一个你觉得舒服的阈值。
为了将 RGB 转换为 L*a*b,我找到了这个页面:http ://cookbooks.adobe.com/post_Useful_color_equations__RGB_to_LAB_converter-14227.html
注意:这基本上是获得色差的最快(尽管有点脏)的方法。我说脏是因为有更复杂的算法在色谱的更饱和端不会失真。如果您想查看最新的算法,请查看此维基百科:http ://en.wikipedia.org/wiki/Color_difference 。
如果要将 RGB 转换为 UIColor,可以使用这两个内联函数:
#define RGB(r, g, b) [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1]
#define RGBA(r, g, b, a) [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:a]
然后像这样使用它们:
UIColor *color = RGB(100,100,100);
为 UIColor+RGB 创建类别。
在.h
#import <UIKit/UIKit.h>
@interface UIColor (RGB)
+(UIColor *)colorWithRedInt:(NSInteger)red greenInt:(NSInteger)green blueInt:(NSInteger)blue alpha:(CGFloat)alpha;
+(UIColor *)commonTextColor;
+(UIColor *)tabBarColor;
@end
英寸
#import "UIColor+RGB.h"
@implementation UIColor (NormalizedRGB)
+(UIColor *)colorWithRedInt:(NSInteger)red greenInt:(NSInteger)green blueInt:(NSInteger)blue alpha:(CGFloat)alpha
{
return [self colorWithRed:red/256.0 green:green/256.0 blue:blue/256.0 alpha:1.0];
}
@end