为什么要做HSL转RGB的原因,设计不想多谈,仁者见仁智者见智。本文的价值,是希望能帮助需要的朋友少走弯路,仅此而已。
Microsoft Office支持的色彩模式有两种:RGB和HSL。HSL由于其直观性,是设计最为常用的色彩模式。在单一形状的颜色调整中,HSL可以直接在Office中操作,虽然比RGB多了一步切换,但也不是什么大事,习惯就无所谓。不过如果要进行批量改色,那么选择形状→填充→其他填充→自定义→修改RGB或HSL值,就显得繁琐无比。而目前支持批量修改颜色的插件几乎没有或者功能不全,无法达到设计的目的,于是设计萌生了自己做一个伪插件的念头。
图1PPT中每次操作,让批量改色无比繁琐
首先,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是标准的红色,它的RGB值应该是255,0,0。为什么这里G、B值是1呢?
这是因为色彩模式的值是取整的,而计算的过程中,会产生小数。小数经过四舍五入后,会有误差。比如H=1时,G=5.23333。
图10 小数导致的误差
所以我们要对K12、K13、K14单元格数据进行四舍五入。那么选择哪一种舍入法呢?
图11 Round()与RoundDown()舍入结果对比
一般的舍入,通常用Round()函数,但通过与RoundDown()函数对比,设计更喜欢后者。原因是RoundDown()舍入后,符合标准红色的RGB值。。
因此,K12进行RoundDown()舍入后的公式是这样子的,K13、K14同理。
=ROUNDDOWN(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,0)
图12 K12、K13、K14公式增加RoundDown()函数进行舍入
设计也想转换公式到此为止,可惜,出现了一个大问题。
图12 蹊跷的数值
当设计满心欢喜的测试时,居然发现青色的RGB居然是(0,255,31)。但实际应该是(0,255,255)。误差如此之大。公式究竟哪里出了问题?
经过无数次排除后,发现公式根本没问题。偶然间,设计看到hk=B3/360。鬼使神差的把360修改为255。。
图13 把h/360改为h/255
额,瞬间风化。。尼妹的维基百科。。。。坑啊。。
可是为什么会出现这种情况?
可能是因为这里的算法是将色调看成一个360的光环,而Office中也许不是这样。所以网上代码那么多,也不是全然搬来就能用,必须改造和取舍。
接着如果想看RGB的颜色,可以通过VBA实现。在开发工具选项卡,点查看代码进入VBA。如果没有开发工具,请在功能区空白区域右键→自定义功能区→右侧勾选开发工具→确定。
图14 开发工具→查看代码→给Worksheet对象选择SelectionChange事件
选择事件后,会自动插入PRivate Sub….End Sub私有调用代码。我们只需要在之间输入下面代码,很简单。
Dim r, g, b
r = Range("f3")
g = Range("g3")
b = Range("h3")
Range("A3").Interior.Color = RGB(r, g, b)
输完以后,关闭VBA,返回EXCEL主界面。
图15 颜色根据RGB值而变
这样我们只需要修改HSL值,RGB值就自动计算得到了,颜色也能预览。
根据这个基本公式,设计这个VBA菜鸟在求教别人、网上查资料后,做出了一个DIY的EXCEL VBA小工具,将EXCEL公式用VBA实现。修改初始色、设置步长和颜色数,左侧自动刷出递进颜色。由于代码太多,不便贴出,可以下载附件,查看EXCEL里的VBA代码。
图16 VBA菜鸟做的小工具(下载附件可得)
这个小工具怎么用呢?修改好右侧的数值,复制左侧的颜色单元格。打开PPT,点开始→粘贴→选择性粘贴→增强型图元文件→选中图片右键→组合→取消组合→是→选中形状右键→取消组合→删除背景透明框→得到多个纯色矩形。(Word跟PPT略有不同,大致步骤如此)
图17 将Excel中的递进颜色导入PPT或WORD中
然后我们就可以像操作普通形状那样进行设计了。本文也到此结束了。
菜鸟真的永远是菜鸟?菜鸟只能永远山寨和模仿?我想不是的。高手也曾菜鸟过,但他们之所以成为高手,除了天赋、性格、思维、专业学习、技术等,更多的是兴趣和坚持。菜鸟什么都可以没有,唯独不能缺少这两样。我用这个自勉,不忘初心,用菜鸟的心发现设计之美。本文是菜鸟所写,有所疏漏和小错误难免,体谅则个。