2008-10-03 78 views
14

我试图在窗体上看到一些值。它们的取值范围是0到200,我希望0左右的是绿色,当它们到200时变为鲜红色。颜色缩放功能

基本上,函数应该根据输入的值返回颜色。有任何想法吗 ?

回答

17

基本上,对于两个值之间平滑过渡的一般方法是下面的函数:

function transition(value, maximum, start_point, end_point): 
    return start_point + (end_point - start_point)*value/maximum 

即给定的,可以定义确实为三元组(RGB,HSV等)转换的功能。

function transition3(value, maximum, (s1, s2, s3), (e1, e2, e3)): 
    r1= transition(value, maximum, s1, e1) 
    r2= transition(value, maximum, s2, e2) 
    r3= transition(value, maximum, s3, e3) 
    return (r1, r2, r3) 

假设你有RGB色彩为小号ē三胞胎,你可以使用transition3功能原样。然而,通过HSV色彩空间会产生更多的“自然”转换。因此,考虑到转换功能(从Python colorsys模块无耻地窃取并转换为伪代码:):

function rgb_to_hsv(r, g, b): 
    maxc= max(r, g, b) 
    minc= min(r, g, b) 
    v= maxc 
    if minc == maxc then return (0, 0, v) 
    diff= maxc - minc 
    s= diff/maxc 
    rc= (maxc - r)/diff 
    gc= (maxc - g)/diff 
    bc= (maxc - b)/diff 
    if r == maxc then 
     h= bc - gc 
    else if g == maxc then 
     h= 2.0 + rc - bc 
    else 
     h = 4.0 + gc - rc 
    h = (h/6.0) % 1.0 //comment: this calculates only the fractional part of h/6 
    return (h, s, v) 

function hsv_to_rgb(h, s, v): 
    if s == 0.0 then return (v, v, v) 
    i= int(floor(h*6.0)) //comment: floor() should drop the fractional part 
    f= (h*6.0) - i 
    p= v*(1.0 - s) 
    q= v*(1.0 - s*f) 
    t= v*(1.0 - s*(1.0 - f)) 
    if i mod 6 == 0 then return v, t, p 
    if i == 1 then return q, v, p 
    if i == 2 then return p, v, t 
    if i == 3 then return p, q, v 
    if i == 4 then return t, p, v 
    if i == 5 then return v, p, q 
    //comment: 0 <= i <= 6, so we never come here 

,你可以有代码如下:

start_triplet= rgb_to_hsv(0, 255, 0) //comment: green converted to HSV 
end_triplet= rgb_to_hsv(255, 0, 0) //comment: accordingly for red 

maximum= 200 

… //comment: value is defined somewhere here 

rgb_triplet_to_display= hsv_to_rgb(transition3(value, maximum, start_triplet, end_triplet)) 
7
red = (float)val/200 * 255; 

green = (float)(200 - val)/200 * 255; 

blue = 0; 

return red << 16 + green << 8 + blue; 
+0

这将使中点(100)puke green:rgb(127,127,0)。你会希望你的中点是一个明亮的黄色或橙色。见:http://stackoverflow.com/questions/168838/color-scaling-function#168980 – 2008-10-03 21:30:55

+1

我同意这一点,它不会看起来不错,但我是一个编码器和中点不是规范的一部分;) – 2008-10-03 21:36:02

1

翻翻this wikipedia article我个人会选择一个路径通过一个色彩空间,和值映射到该路径。

但这是一个直接的功能。我认为你可能更适合使用可以给你Hex的快速颜色找到的javascript颜色选择器,并且可以存储十六进制。

3

找一个你喜欢,你喜欢(RGB2 =#FF0000,例如),然后绿色(RGB 1 =#00FF00,EG)和红色计算这样

R = R1 * (200-i)/200 + R2 * i/200 
G = G1 * (200-i)/200 + G2 * i/200 
B = B1 * (200-i)/200 + B2 * i/200 
2

为了获得最佳的控制和颜色准确的效果,你应该使用HSV色彩空间。使用HSV,您可以轻松地将色调,饱和度和/或亮度分开调整。然后,您将转换为RGB。

7

你不说在什么环境下你这样做。如果你能HSV colors工作,这将是很容易通过设置S = 100 V = 100,并通过确定H至事:

H = 0.4 * value + 120 

Converting from HSV to RGB也相当容易。

[编辑]注意:与其他一些建议的解决方案相比,这将改变颜色绿色 - >黄色 - >橙色 - >红色。

0

如果您使用红色线性斜坡和绿色价值,如彼得帕克建议,价值100的颜色基本上是puke green(127,127,0)。理想情况下,您希望它在该中点处是明亮的橙色或黄色。对于这一点,你可以使用:

Red = max(value/100, 1) * 255 
Green = (1 - max(value/100, 1)) * 255 
Blue = 0 
2

在@ tzot代码扩展...您还可以设置一个中间点在起点和终点,这可能是有用之间,如果你想有一个“过渡色“!

//comment: s = start_triplet, m = mid_triplet, e = end_triplet 
function transition3midpoint = (value, maximum, s, m, e): 
    mid = maximum/2 
    if value < mid 
     return transition3(value, mid, s, m) 
    else 
     return transition3(value - mid, mid, m, e)