有时候,我们需要把某种数值大小的渐变 以 颜色渐变的方式表示出来。如果用RGB模式表示颜色,这种渐变常常达不到理想的效果。因为RGB进行内插值后,倾向于混为一体。比如在RGB空间中,取橙色(255,128,0)和浅蓝色(0,128,255),那么这2种颜色的中间值会是(128,128,128)即灰色,而这不是我们希望看到的。 另外,我们眼中的相接近的颜色,其RGB数值相距遥远。
所以,当我们需要通过颜色渐变表达数值变化的时候,建议使用HSB颜色空间。
1.理解HSB颜色空间
HSB(HSV) 通过色相/饱和度/亮度三要素来表达颜色.
H(Hue):表示颜色的类型(例如红色,绿色或者黄色).取值范围为0—360°.其中每一个值代表一种颜色.(红、橙、黄、绿、青、蓝、紫)
S(Saturation):颜色的饱和度.从0到1.有时候也称为纯度.(0表示灰度图,1表示纯的颜色)(相当于说有没有杂质)
B(Brightness or Value):颜色的明亮程度.从0到1.(0表示黑色,1表示特定饱和度的颜色)。(黑、白)
这里有一个理解HSB的网站:http://web.bentley.edu/empl/c/ncarter/MA307/color-converter.html
根据上面这个网址的演示,可以了解到:
(1)如果要不同颜色之间发生变化,只需要H值发生变化,S=1,B=1.这样就很明显。
(2)如果在一个选定的颜色发生变化,只需要S值变化, H=固定值,B=1.这样就可以了。
(3)如果要在黑色、白色之间变化,则只需B变化,H=0°,S=0;
2.常见颜色的H值
红(0°或360°)、黄(60°)、绿(120°)、青(180°)、蓝(240°)、洋红(300°)。
3.现在的问题是计算机采用的RGB模式显示颜色,所以需要将HSB的值转化为RGB值,用来显示。转换函数设计如下。
(1)算法设计
当RGB的值位于【0,1】时,参考http://zh.wikipedia.org/wiki/HSL%E5%92%8CHSV%E8%89%B2%E5%BD%A9%E7%A9%BA%E9%97%B4#.E4.BB.8E_HSV_.E5.88.B0_RGB_.E7.9A.84.E8.BD.AC.E6.8D.A2,计算公式如下:
如果要得到【0,255】之间的RGB值,还需转换一次
(R,G,B)=(255*r,255*g,255*b)。
(2)算法实现 (C语言)
int* HSB2RGB(float h,float s,float v ) { if(h<0 || h> 360.0f) return NULL; if(s<0.0f||s>1.0f) return NULL; if(v<0.0f||v>1.0f) return NULL; float r = 0, g = 0, b = 0; int i = (int) ((h / 60) % 6); float f = (h / 60) - i; float p = v * (1 - s); float q = v * (1 - f * s); float t = v * (1 - (1 - f) * s); switch (i) { case 0: r = v; g = t; b = p; break; case 1: r = q; g = v; b = p; break; case 2: r = p; g = v; b = t; break; case 3: r = p; g = q; b = v; break; case 4: r = t; g = p; b = v; break; case 5: r = v; g = p; b = q; break; default: break; } int *temp=new int[3]; temp[1]= (int) (r * 255.0); /*这里的r,g,b要乘以255,是因为前面计算的r,g,b 都是位于【0,1】之间的*/ temp[2]= (int) (g * 255.0); temp[3]= (int) (b * 255.0); return temp; }
(3)示例:
红色的HSV=(0.0,1.0,1.0)时,计算出来的RGB=(255,0,0);