為什麼要做HSL轉RGB的原因,設計不想多談,仁者見仁智者見智。本文的價值,是希望能幫助需要的朋友少走彎路,僅此而已。
Microsoft Office支持的色彩模式有兩種:RGB和HSL。HSL由於其直觀性,是設計最為常用的色彩模式。在單一形狀的顏色調整中,HSL可以直接在Office中操作,雖然比RGB多了一步切換,但也不是什麼大事,習慣就無所謂。不過如果要進行批量改色,那麼選擇形狀→填充→其他填充→自定義→修改RGB或HSL值,就顯得繁瑣無比。而目前支持批量修改顏色的插件幾乎沒有或者功能不全,無法達到設計的目的,於是設計萌生了自己做一個偽插件的念頭。
圖1 PPT中每次操作,讓批量改色無比繁瑣
首先,RGB和HSL都是計算機成熟的色彩模式,那麼網上肯定有相關的實現方式。於是在維基百科上,看到了這條百科:http://zh.wikipedia.org/wiki/HSL和HSV色彩空間
【從HSL到RGB的轉換】(轉換公式來自維基百科)
給定HSL空間中的(h,s,l)值定義的一個顏色,帶有h在指示色相角度的值域[0,360)中,分別表示飽和度和亮度的s和l在值域[0,1]中,相應在RGB空間中的(r,g,b)三原色,帶有分別對應於紅色、綠色和藍色的r,g和b也在值域[0,1]中,它們可計算為:
首先,如果s=0,則結果的顏色是非彩色的、或灰色的。在這個特殊情況,r,g和b都等於l。注意h的值在這種情況下是未定義的。
當s≠0的時候,可以使用下列過程:
剛開始看這段,設計這個編程和EXCEL菜鳥也著實頭疼,但既然都是計算,EXCEL肯定是能做的,於是設計硬著頭皮在EXCEL中開始弄數據。
圖2 單元格填入文字和初始數字
開始分析公式,“給定HSL空間中的(h,s,l)值定義的一個顏色,帶有h在指示色相角度的值域[0,360)中,分別表示飽和度和亮度的s和l在值域[0,1]中,相應在RGB空間中的(r,g,b)三原色,帶有分別對應於紅色、綠色和藍色的r,g和b也在值域[0,1]中”。要注意的是,公式裡的h/s/l都是轉換後的,h值域是[0,360],s和l的值域是[0,1]。這句話很重要,設計剛開始也是犯了不少錯誤,就是沒搞清這裡的值域。那怎麼轉換值域呢,H要除以360(這裡有坑,最後談),S和L要分別除以255。如圖2中,HSL(0,255,128)轉換值域後是(0,1,0.5)。這也是為什麼維基上的公式,要判斷L跟1/2的關系的問題所在。
繼續分析:“首先,如果s=0,則結果的顏色是非彩色的、或灰色的。在這個特殊情況,r,g和b都等於l”。用EXCEL理解的話來說是這樣的:如果代表飽和度S的單元格C3=0,那麼F3(R)、G3(G)、H3(B)都等於D3,否則繼續判斷。由於最後還要給G3、H3復制公式,所以鎖定D3。因此F3(R)單元格的第一步公式是:if($C$3=0,$D$3,)。這個條件判斷先留著。
然後繼續分析飽和度s≠0的情況。
注意,這裡的l是轉換過值域的亮度,所以我們需要先把D3除以255,再來跟0.5相比較。在K3輸入q的公式:=IF(D3/255<0.5,D3/255*(1+C3/255),D3/255+C3/255-D3/255*C3/255)
圖3 在K3輸入q的公式
接下來看p
在K4輸入p的公式:=2*D3/255-K3
圖4 在K4輸入p的公式
繼續看
在K5輸入hk的公式:=B3/360
在K6輸入tR的公式:=K5+1/3
在K7輸入tG的公式:=K5
在K8輸入tB的公式:=K5-1/3
圖5 在K5-K8分別輸入hk、tR、tG、tB的公式
繼續,難點來了,這裡tC的含義
這裡的tc是指tR、tG、tB的任意一個,三者都滿足這個條件公式。
K9單元格輸入公式:=IF(K6<0,K6+1,IF(K6>1,K6-1,K6))
K10單元格輸入公式:=IF(K7<0,K7+1,IF(K7>1,K7-1,K7))
K11單元格輸入公式:=IF(K8<0,K8+1,IF(K8>1,K8-1,K8))
圖5 這樣我們就得到了分別對應tR、tG、tB的三個tC值
接下來看公式的最後一步
這一步分別把三種tC代入進去,就分別得到了R、G、B的值。所以這一步的公式,我們先做R的。此時再加三個單元格nR、nG、nB作為過渡,方便後續引用。
根據上面的公式,nR(即K12單元格)在S≠0時,EXCEL的公式應該是這樣的
=IF(K9<1/6,K4+(K3-K4)*6*K9,IF(AND(K9<1/2,K9>=1/6),K3,IF(AND(K9<2/3,K9>=1/2),K4+(K3-K4)*6*(2/3-K9),K4)))
因K12對應的nR在給nG、nB復制公式的時候,K9要分別變為K10、K11,而其他不變。所以公式應該給q、p也就是K3、K4加鎖定單元格。
=IF(K9<1/6,$K$4+($K$3-$K$4)*6*K9,IF(AND(K9<1/2,K9>=1/6),$K$3,IF(AND(K9<2/3,K9>=1/2),$K$4+($K$3-$K$4)*6*(2/3-K9),$K$4)))
圖6 把公式復制到nR後面的單元格裡
此時得到的nR的值域為[0,1],所以在需要轉換回[0,255]的值域。
所以nR的公式最後再乘以255。
=IF(K9<1/6,$K$4+($K$3-$K$4)*6*K9,IF(AND(K9<1/2,K9>=1/6),$K$3,IF(AND(K9<2/3,K9>=1/2),$K$4+($K$3-$K$4)*6*(2/3-K9),$K$4)))*255
圖7 公式乘255轉換回[0,255]的值域
把nR的公式復制給nG、nB單元格,這應該都會,按住控制柄的小黑點,拖動。
圖8 把公式復制給nG、nB
然後,因R單元格裡的數值之前已經有一個當s=0的判斷:=if($C3=0,$D$3,)
因此,R的新公式需要把這個判斷加上。此時公式變為:
F3(R)單元格的公式是:=if($C3=0,$D$3,K12)
G3(G)單元格的公式是:=if($C3=0,$D$3,K13)
H3(B)單元格的公式是:=if($C3=0,$D$3,K14)
圖9 公式填入F3、G3、H3單元格
至此,從維基百科獲取的公式就轉換為EXCEL裡了。但這裡有一個問題。HSL:0,255,128是標准的紅色,它的RG