我正在尝试绘制一个完整的RGB颜色贴图,最终允许用户通过在任何位置点击该可视贴图来选择颜色。我目前的代码如下:
- (void)drawRect:(CGRect)rect
{
CGContextRef c = UIGraphicsGetCurrentContext();
for (float x=0; x<320; x++) {
for (float y=0; y<416; y++) {
float r = x / 320;
float g = y / 416;
float b = (y < 208) ? y / 208 : (416 - y) / 208;
CGContextSetRGBFillColor(c, r, g, b, 1.0);
CGContextFillRect(c, CGRectMake(x, y, 1, 1));
}
}
}
结果还不错,但我还不满意。光谱错过了包括白色在内的鲜艳色彩。原因很清楚:红色,绿色和蓝色不会同时达到1.0。
您是否有任何建议如何改进该地图,以便它代表RGB色彩空间的全部光谱?
感谢您的所有投入!
更新
正如 Josh Caswell 所建议的,我使用了HSB颜色空间和以下代码:
- (void)drawRect:(CGRect)rect
{
CGContextRef c = UIGraphicsGetCurrentContext();
int size = 20;
for (float x=0; x<320; x+=size) {
float s = x < 160 ? 1 : (320 - x) / 160;
float b = x < 160 ? x / 160 : 1;
for (float y=0; y<416; y+=size) {
float h = y / 416;
[[UIColor colorWithHue:h saturation:s brightness:b alpha:1.0] setFill];
CGContextFillRect(c, CGRectMake(x, y, size, size));
}
}
}
这导致以下输出完全符合我的需要。
感谢所有输入!
答案 0 :(得分:7)
嗯,你试图将一个三维物体压平在一个平面上。 RGB颜色基本上代表立方体内的一个点。将RGB实体映射到曲面上可能在数学上是可行的,但对于这种颜色选择目的可能不会特别直观。
使用HSB可能会有更好的运气,HSB更像是一个圆周呈角色的圆柱体。您可以“展开”圆柱体,将色调映射到y坐标,然后沿x轴改变亮度或饱和度 - 您可以进行一些简单的测试来确定哪个组件对您的应用更重要。如果您认为有必要将双指滑动用于第三个组件,则可以使用双指滑动。
HSB在X轴上饱和:
X轴亮度:
饱和度和亮度相等且均在X轴上:
如果您需要白色,当S = 0%,B = 100%时,您可以沿着一侧粘贴条带,或尝试S = 1 / B.
答案 1 :(得分:2)
我认为推导它的方法是这样的:
水平方向,对于每个像素,选择r g b的比率,例如“0,0,1”
从上到下绘制像素,亮度从0到1。
将每个像素导出为pixel = brightness * (r,g,b)
当您横向移动时,将R G B迭代为:
000, 001, 010, 011, 100, 101, 110, 111
如果使用3个正弦计算,您可以使用公式实现此目的,并同时处理插值。
这解决了白色和黑色的问题,并为您提供了大量的色彩空间。如果你绝对需要色彩空间的每个像素,你需要以不同的方式进行水平插值,你需要2 ^ 8而不是8个控制点。
答案 2 :(得分:2)
您试图在二维表面上表示三维色彩空间。您不太可能找到足够的单个表面。
您需要选择两部分。