色相(H)飽和度(S)明度(L)與RGB的轉換以及在android上的試驗

最近突然想在android的SurfaceView上實現一個類似windows上畫圖顏色選擇面板那種顏色和彩虹差不多排列的效果,以下是嘗試。



HSL的H(hue)分量,代表的是人眼所能感知的顏色範圍,這些顏色分佈在一個平面的色相環上,取值範圍是0°到360°的圓心角,每個角度可以代表一種顏色。色相值的意義在於,我們可以在不改變光感的情況下,通過旋轉色相環來改變顏色。在實際應用中,我們需要記住色相環上的六大主色,用作基本參照:360°/0°紅、60°黃、120°綠、180°青、240°藍、300°洋紅,它們在色相環上按照60°圓心角的間隔排列。


HSL的S(saturation)分量,指的是色彩的飽和度,它用0%至100%的值描述了相同色相、明度下色彩純度的變化。數值越大,顏色中的灰色越少,顏色越鮮豔,呈現一種從理性(灰度)到感性(純色)的變化。


HSL的L(lightness)分量,指的是色彩的明度,作用是控制色彩的明暗變化。它同樣使用了0%至100%的取值範圍。數值越小,色彩越暗,越接近於黑色;數值越大,色彩越亮,越接近於白色。


a) RGB→HSL
1.把RGB值用(0, 1)表示
2.找出RGB中的最大值。
3.計算L(明度):L=(max(R,G,B) + min(R,G,B))/2
4.如果最大和最小的顏色值相同,即表示灰色,那麼S(飽和度)定義爲0,而H(色調)未定義並在程序中通常寫成0。
5.否則L(明度)計算S(飽和度)
If L<0.5, S=(max(R,G,B) -min(R,G,B))/(max(R,G,B)  + min(R,G,B))
If L>=0.5, S=(max(R,G,B) -min(R,G,B))/(2.0-maxcolor-min(R,G,B))
6.計算H(色調)
If R=max(R,G,B)
 H=(G-B)/(max(R,G,B)-min(R,G,B))
If G=max(R,G,B),
H=2.0+(B-R)/(max(R,G,B)-min(R,G,B))
If B=max(R,G,B),
H=4.0+(R-G)/(max(R,G,B)-min(R,G,B))
H=H*60.0
if(H<0) 
H+=360
說明:1,由步驟3的式子可以看出L(明度)僅與圖像的最多顏色成分和最少的顏色成分的總量有關。L(明度)越小,圖像越趨於黑色。L(明度)越高圖像越趨於明亮的白色。
  2,由步驟5的式子可以看出S(飽和度)與圖像的最多顏色成分和最少的顏色成分的差量有關。S(飽和度)越小,圖像越趨於灰度圖像。S(飽和度)越大,圖像越鮮豔,給人的感覺是彩色的,而不是黑白灰的圖像。
  3,H(色調)決定了人對圖像的不同的顏色感受。
  4,從第6步的計算看,H(色調)分成0~6區域。RGB顏色空間是一個立方體而HSL顏色空間是兩個六角形錐體,其中的H(色調)是RGB立方體的主對角線。因此,RGB立方體的頂點:紅、黃、綠、青、藍和品紅就成爲HSL六角形的頂點,而數值0~6就告訴我們H(色調)在哪個部分。
以上整理自百度百科

b) HSL→RGB
private void HSL2RGB(double H, double S, double L){//此處HSL均轉化到(0, 1)
double var1, var2;
if(S == 0){
R = (int)(L * 255.0);
G = (int)(L * 255.0);
B = (int)(L * 255.0);
}else{
if(L < 0.5)
var2 = L * (1 + S);
else
var2 = (L + S) - (S * L);
var1 = 2.0 * L - var2;

R = (int)(255.0 * Hue2RGB(var1, var2, H + (1.0/3.0)));
G = (int)(255.0 * Hue2RGB(var1, var2, H));
B = (int)(255.0 * Hue2RGB(var1, var2, H - (1.0/3.0)));
}
}

private double Hue2RGB(double v1, double v2, double vH){
if (vH < 0) 
vH += 1;
   if (vH > 1) 
    vH -= 1;
   if (6.0 * vH < 1) 
    return v1 + (v2 - v1) * 6.0 * vH;
   if (2.0 * vH < 1) 
    return v2;
   if (3.0 * vH < 2) 
    return v1 + (v2 - v1) * ((2.0 / 3.0) - vH) * 6.0;
   return (v1);
}
最後實現效果如下(其中L固定爲0.5):





發佈了25 篇原創文章 · 獲贊 1 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章