寫在前面
在講這個之前,首先簡單介紹一下什么是RGB,什么是HSB。
RGB色彩模式是工業(yè)界的一種顏色標準,是通過對紅(R)、綠(G)、藍(B)三個顏色通道的變化以及它們相互之間的疊加來得到各式各樣的顏色的,RGB即是代表紅、綠、藍三個通道的顏色,這個標準幾乎包括了人類視力所能感知的所有顏色,是運用最廣的顏色系統(tǒng)之一。顯示器大都是采用了RGB顏色標準。
HSB又稱HSV,表示一種顏色模式:在HSB模式中,H(hues)表示色相,S(saturation)表示飽和度,B(brightness)表示亮度。HSB模式對應的媒介是人眼。
(以下為了避免RGB的B和HSB的B混淆,HSB統(tǒng)一寫作HSV)
RGB的色彩模型是一個立方體,而HSV的色彩模型一般為圓柱體或圓錐體。詳見下圖:
當然,色彩模式還有很多,諸如:CMYK,ABL等等,本文不多做介紹。
詳解轉(zhuǎn)換公式之前,需要理解以下幾個重要概念。
概念一:H,和RGB之間的關(guān)系是什么。
相對于RGB,HSV模式更便于描述人眼對與顏色的感覺。如圖的HSV椎形坐標,橫截面從下往上亮度值V從0%到100%遞增,橫截面的中心(即圓心位置)是灰色的,隨著半徑增大(相對遠離圓心位置),飽和度S從0向100%遞增,色相H取值0°~360°,代表截面上紅、黃、綠、青、藍、紫的顏色變化。
HSV坐標系最頂部的截面最外圈,飽和度和亮度都是100%,隨著色相從0°到360°變化,RGB值的變化如上圖,紅色、綠色、藍色分別位于0°、120°、240°;0°到60°之間綠色分量均勻增加,60°到120°之間紅色分量均勻減少,以此類推。設(shè)置S=V=100%,調(diào)整H的值觀察RGB的變換就能發(fā)現(xiàn)這個規(guī)律。如下圖:
根據(jù)上圖可知,不論H處于哪個位置,RGB值中的(r,g,b)三個數(shù)值中最大值一定是255,最小值一定是0。
而由此可見,與H相關(guān)的,是RGB值中的(r,g,b)三個數(shù)值中最大的那個值。
概念二:關(guān)于飽和度的解析
在亮度B=100%時,飽和度S降低,即“不飽和度”會升高,會使得RGB與最大值255相差的部分對應增大,RGB三個分量越趨于相同就使得圖像越灰。而這個“不飽和度”可以用1-S來代替。
而RGB三個分量中的單個分量的數(shù)值中,經(jīng)過我在PS中對色相立方體的多次測試觀察,可以推斷。如下圖,當只改變最大值且使它保持最大值時,顏色只會在Y軸縱向偏移,而改變最小值且使它保持最小值,顏色只會在X軸進行橫向偏移。由此可見max是由純色向著黑色進行漸變的,max越小,顏色越暗,min是由純色向著白色進行漸變的,min越大,顏色越亮。
概念三:關(guān)于明度的解析
在明度開始下降時,RGB的三個分量,都會開始同時下降,下降遞減的值,是根據(jù)分量本身來定的。
根據(jù)“概念二”可知,明度相關(guān)的是RGB的最大值。
如:rgb(255,255,255)
那么這個時候的明度是100%。
?R=255/255=100%=1
G=255/255=100%=1
B=255/255=100%=1
如:rgb(126,24,99)
那么這個時候的明度是49%。
R=126/255=49=0.49
G=25/255=10=0.1
B=99/255=39=0.39
概念四:顏色的偏移與反偏移
以PS的色相立方體為模型,H從最底下0°開始上升,到360°=0°,除去0°和360°兩個頂點同為紅色外,60°黃色,120°綠色,180°青色,240°藍色,300°紫色。
以這七個位置作為原點,向右是正向偏移,即f,向左是反向偏移,即1-f。
正向偏移取的是這六個區(qū)間內(nèi)的左邊的值,反向偏移取的是這六個區(qū)間右邊的值。
如:130°,相對120°的綠色,正向偏移了10°,相對180°的青色反向偏移了50°
而這個時候的綠色為255,藍色從左自右逐漸遞增,紅色始終為0。
由此可見正向偏移得到的是最大值max,反向偏移得到的是中間值med。
HSV轉(zhuǎn)RGB:
以下是查閱(參考資料1)獲得的HSV轉(zhuǎn)RGB算法公式,這個公式成立首先有以下幾個個必要條件,
第一:因為HSV中的S和V數(shù)值單位是百分比,在進入運算的時候,需要把S和V的數(shù)值除以100
第二:?H<360°
第三:? 最后得出的RGB值,需要乘以255
這幾點很重要!!!原文中沒有指出!!!這里提醒一下!!!
首先:確定H的位置。
在確定H的值之前,需要知道H代表的是什么,以及H和RGB之間的關(guān)系。
根據(jù)上文提到,H代表的是色相,以及“概念一”中提到的可以得知:
h1=[H/60] mod6?
詳解:h1等于H除以60,取整數(shù)部分,然后除以六,求出余數(shù)。
H/60的整數(shù)部分除以六,求出余數(shù)。是確定H在的顏色區(qū)域。而H/60的小數(shù)部分,即為在這個顏色范圍中偏移的值。
如果h1=0,那么顏色在0°-60°區(qū)域
如果h1=1,那么顏色在60°-120°區(qū)域
如果h1=2,那么顏色在120°-180°區(qū)域
如果h1=3,那么顏色在180°-240°區(qū)域
如果h1=4,那么顏色在240°-300°區(qū)域
如果h1=5,那么顏色在300°-359°區(qū)域
f=H/60-h1
詳解:這里變量f求的是顏色在色相環(huán)中對應區(qū)域的偏移值。已知[H/60] 是確定區(qū)域作用,
根據(jù)上文提到,H/60的小數(shù)部分是求顏色范圍的偏移值
,那么h/60-[h/60]=H/60-h1就是求出求出這個偏移值。
p=? ?V*(1-S)
詳解:這里變量p求的是實際RGB中的最小值,即min。
根據(jù)“概念二”得知,1-S求的是不飽和度,則1-S求的是飽和度最低的值,也就是RGB中三個分量中與255相差大的值。這個值乘以明度,即是RGB三個分量中最小的那個值。
q=? ?V*(1-f*s)
詳解:這里變量q求的是實際RGB中的最大值,即max。
根據(jù)“概念一”可以得知,與最大值相關(guān)的,就是H,f是h在指定色相區(qū)域內(nèi)的偏移角度,f*s是RGB三個分量中最大的那個值的飽和度,1-f*s得到的就是最大值不飽和度,再乘以明度即是RGB三個分量中最大的那個值。
t=V*(1-(1-f)*s)
詳解:這里變量q求的是實際RGB中的中間值,即med。
根據(jù)“概念一”可以得知,與最大值相關(guān)的,就是H,f是h在指定色相區(qū)域內(nèi)的偏移角度,而根據(jù)“概念4”可以得知,1-f就是反向偏移,反向偏移求的就是中間值,(1-f)*s就是反向偏移的中間值乘以飽和度。(1-(1-f)*s)就是反向偏移的中間值的不飽和度,最后再把明度乘進去,V*(1-(1-f)*s),求的就是RGB的中間值。
當把max,med,min,三個對應RGB中分量的值求出來之后,開始判斷條件,分別代入。
判斷H的位置,將max,med,min分別代入RGB中。
根據(jù)上面的式子,我們可以知道,判斷H位置的變量是h1,
結(jié)合“概念一”中提到的,紅色、綠色、藍色分別位于0°、120°、240°;0°到60°之間綠色分量均勻增加,60°到120°之間紅色分量均勻減少,等等。以及表格的內(nèi)容。
那么就可以將max,med,min,找到對應的位置,填入RGB的三個分量中去。
這里不作詳細解釋,上面圖片里的式子寫的很清楚,自行理解。
一定要記得代入之后,乘以255!
RGB轉(zhuǎn)HSV:
以下是查閱(參考資料1)獲得的RGB轉(zhuǎn)HSV算法公式,其中求V的算法是錯誤的。
因為(參考資料1)中沒有說明算法中的max及min的相關(guān)說明。所以我在這里困惑了很久。
通過推導(參考資料2)的過程,可以得知,max和man分別代表的是兩個變量,這兩個變量取自RGB值中的(r,g,b)三個數(shù)值中的最大值及最小值。
那么算法代表的意義就明確起來。
求H的公式詳解:
undefined? ? ?if max=min? ? ?
詳解:當最大值等于最小值時,h可以為任意值,不會影響實際展示出來的顏色。因為RGB值中的(r,g,b)三個數(shù)值都相等。如果RGB的三個數(shù)值相等,那么色彩的范圍在色彩模型中就是圓心的位置,即為黑白灰,與色相H無關(guān)。
60°*(g-b)/(max-min)+0°? ? ? ? if max =r and g>=b? ? ?
詳解:根據(jù)上面總結(jié)的規(guī)律可以得知如果最大值為r,那么H的取值范圍就是300°-360°或0°-60°,且如果要滿足g大于等于b,假設(shè)g=b,那么g和b只能為0。當g>b時,H的取值范圍就變?yōu)?°-60°,且角度一定是R向G進行偏移,這個時候只需要計算R向著G的偏移度數(shù),即可求出H的值。 g-b為差值,max-min是差值分量,(g-b)/(max-min)是求偏移分量,60*(g-b)/(max-min)是求在這個取色范圍中偏移度數(shù)。60*(g-b)/(max-min)+0°是求所在色彩區(qū)域距離0°的差值,需要加上。
60°*(g-b)/(max-min)+360°? ? ? ? if max =r and b>g ?
詳解:此處是求R值的第二種情況,最大值為r,那么H的取值范圍就是300°-360°或0°-60°,且如果要滿足b大于g,當g>b時,H的取值范圍就變?yōu)?00°-360°,且角度一定是B向R進行偏移,這個時候只需要計算B向著R的偏移度數(shù),即可求出H的值。 g-b為差值,max-min是差值分量,(g-b)/(max-min)是求偏移分量,60*(g-b)/(max-min)是求在這個取色范圍中偏移度數(shù)。60*(g-b)/(max-min)+360°是求所在色彩區(qū)域距離0°的差值,需要加上。
60°*(b-r)/(max-min)+120°? ? ? ? if max =g?
詳解:根據(jù)上面總結(jié)的規(guī)律可以得知如果最大值為g,那么H的取值范圍就是60°-240°。 b-r為差值,max-min是差值分量,(b-r)/(max-min)是求偏移分量,60*(b-r)/(max-min)是求在這個取色范圍中偏移度數(shù),可以為負數(shù),正數(shù)代表G向著B偏移,負數(shù)代表G向著R偏移。60*(g-b)/(max-min)+120°是求所在色彩區(qū)域距離0°的差值,需要加上。
60°*(r-g)/(max-min)+240°? ? ? ? if max =b
詳解:根據(jù)上面總結(jié)的規(guī)律可以得知如果最大值為b,那么H的取值范圍就是120-300°。 r-g為差值,max-min是差值分量,(r-g)/(max-min)是求偏移分量,60*(r-g)/(max-min)是求在這個取色范圍中偏移度數(shù),可以為負數(shù),正數(shù)代表B向著R偏移,負數(shù)代表B向著G偏移。60*(r-g)/(max-min)+240°是求所在色彩區(qū)域距離0°的差值,需要加上。
求S的公式詳解:
0? ? ? ? ? ? if max = 0
詳解:當RGB中的最大值都為0,那么其他兩個值,也一定為0,此時的顏色為黑色。無飽和度,所以飽和度也為0。
(max-min)/max
詳解:這里max代表的是顏色的飽和度最高值,min代表的是顏色飽和度的最低值,因為max與RGB分量的最大值255更為接近,而min與RGB分量的最小值0更為接近。
這里將max作為這個RGB值分量的最大值,即飽和度的最高值,那么min就代表的是不飽和度,將飽和度的最大值減去不飽和度,得到的即是飽和度的數(shù)值。然后將飽和度的數(shù)值除以RGB中的最大分量max,得到的百分比,即使飽和度S的值。
求V的公式詳解:
上面公式圖的V的算法應該是錯誤的,
實際應該是:V=max/255
詳解:根據(jù)“概念三”可以得知,與明度相關(guān)的值只有max,所以直接用max除以RGB顏色值的最大分量,得到的百分比,即是明度。
完。(以上內(nèi)容不保證完全正確,僅供參考)