【发布时间】:2009-09-14 21:05:14
【问题描述】:
我正在尝试在 java 中的画布上进行颜色更改,以表示由颜色表示的值相对于彼此的强弱程度。
rgb 颜色必须是相同的颜色,只是不同的色调,比如白色到灰色到黑色以及介于两者之间的每个灰色阴影。考虑到我所代表的值变化很大,从 -9999999 到正 9999999,如何更改 rgb 值。
【问题讨论】:
标签: java
我正在尝试在 java 中的画布上进行颜色更改,以表示由颜色表示的值相对于彼此的强弱程度。
rgb 颜色必须是相同的颜色,只是不同的色调,比如白色到灰色到黑色以及介于两者之间的每个灰色阴影。考虑到我所代表的值变化很大,从 -9999999 到正 9999999,如何更改 rgb 值。
【问题讨论】:
标签: java
我认为你应该看看 HSL/HSV 而不是 RGB。
虽然 RGB 在本质上是基本的,因为它根据原色来表达颜色,但它不允许您对 R、G 或 B 值进行“可理解的”更改以达到“相似”的颜色。使用 HSL/HSV 模型,您将能够更改亮度/亮度/值 (L/V) 以获得具有不同灰色量的颜色,或更改色相 (H) 以获得整个光谱中的相似颜色.您可以从全亮度(白色)开始,通过降低 L/V 的值来创建较暗的灰色调,最终达到无亮度的颜色(黑色)。
一个很温和的introduction to color theory, for developers is available here。
至于你的问题,你应该用 HSL 来表达你的颜色,随着饱和度值的增加,颜色范围从白色到黑色。当然,如果您想要介于白色和黑色之间的灰色调而不需要任何其他颜色,则应将色调保持在最低限度。
下面是一个关于如何获得颜色范围的简短示例。为简洁起见,我已将颜色填充到数组中,但这不是必需的,因为您可能想立即使用颜色(除了考虑内存要求)。
private Color[] produceColorRange(int steps)
{
float value = 1.0f; //Starting with full brightness
Color[] colors = new Color[steps];
for(int ctr = 0; ctr < steps; ctr++)
{
value = value - (1.0f/steps); //tend to darkness
int rgb = Color.HSBtoRGB(0.7f, 0.0f, value); //create a darker color
//Hue is Blue, not noticeable
//because Saturation is 0
Color color = new Color(rgb);
colors[ctr] = color;
}
return colors;
}
如果你使用上面的方法并绘制一个JFrame,你将能够得到类似于下面的结果(除了我已经修改了色调和饱和度来得到我的颜色范围)。
请注意,如果您想要更简单的方法来获取颜色范围,请使用 Color.WHITE 初始化 Color 对象并调用 color.darker()。当然,你将无法控制增量。
【讨论】:
是的,调整您的价值观以适应您的领域。这取决于您的 RGB 值的存储方式。通常,每个使用 8 位。由于灰色具有 R = G = B,因此您希望将 (-9999999,9999999) 范围内的值缩放到 (0, 255)。
考虑第一个区间中的 x。由于第一个范围也涵盖负数,因此首先进行移位。
x = x + 9999999
现在 x 在区间 (0, 19999998) 中。下一步是将其缩小到 (0, 255)。由于颜色值在该区间内呈线性增长,您所要做的就是:
x = x * 255 / 19999998
现在 x 就像你想要的那样在区间 (0, 255) 中。
一般来说,如果你的初始值在区间 (a, b) 中,并且想要将其转换为 (0, c),应用这个公式:(注意 a 可以是负数)
x = (x - a) * c / (b - a)
因此,如果您的 R、G、B 值是 16 位长,则 c 将为 2**16 = 65536,公式为:
x = (x + 9999999) * 65536 / 19999998
希望对您有所帮助。
【讨论】:
我不完全确定我理解你的问题,但是,如果我理解了:
为什么不将 RGB 值缩放到您范围内的值(从 -9999999 到正 9999999)?此外,将 R、G 和 B 都设置为相同的值,以便您使用灰色阴影来表示值。
像这样:
private final int MIN = -9999999;
private final int MAX = 9999999;
public Color getScaledColor(int val) {
int gray = (int) Math.round((double) (val - MIN) / (double) (MAX - MIN)
* 255.0);
Color color = new Color(gray, gray, gray);
return color;
}
请注意,此解决方案不会为您指定范围内的所有值提供唯一颜色。但也要记住,人眼只能区分这么多的阴影(而 2 * 9999999 + 1 可能比它可以区分的阴影数量多)。
【讨论】:
HSL Color 类实现上面提供的有关 HSL/HSV 的 Wikipedia 链接中提供的公式。
【讨论】: