前言
之前在想如何给自定义的标签生成颜色,初步想法是根据文本的 hash 值得出一个“色调”,然后给予它不同的“亮度”,以生成标签文本和边框的颜色,示例图大概这样子:
我是标签呀
但是 RGB 表示颜色并没有办法直接修改颜色的“亮度”,修改 R、G、B 其中每一个值都会影响颜色的亮度,然后…发现自己从来没有注意过除了 RGB 外的其他色彩空间,例如在 HSL 空间中就可以轻易做到这一点。本文主要想回顾一下日常开发中可能用到的不同的色彩空间,CSS 中支持 RGB、HSL、HWB 三种色彩空间。
色彩空间(色彩模型,Color Space)是对色彩的组织方式,借助色彩空间和针对物理设备的测试,可以得到色彩的固定模拟和数字表示。
RGB
RGB 由三个通道表示一幅图像,分别为红色r,绿色g和蓝色b。这三种颜色的不同组合可以形成几乎所有的其他颜色。我们可以用一个三维直角坐标表示 r、g、b和各颜色的关系
HSL 和 HSB / HSV
HSL、HSB 都是 RGB 的一种表示形式。HSL 表达彩色图像的方式由三个部分组成:Hue(色调、色相)、Saturation(饱和度、色彩纯净度)、Lightness(亮度)。而 HSB 表达彩色图像的方式也是由三个部分组成:Hue(色调、色相)、Saturation(饱和度、色彩纯净度)、Value(明度,也写为 Brightness)。
- 色相(Hue)是色彩的基本属性,就是平常所说的颜色名称,如红色、黄色等,取值为 0 - 360 deg。
- 饱和度(Saturation)是指色彩的纯度,越高色彩越纯,低则逐渐变灰,取 0 - 1,在 HSL、HSB 中,它们的定义是不同的。
- 明度(Value / Brightness)、亮度(Lightness),取 0 - 1。在 HSL 中,亮度越大,颜色越白,反之越黑;在 HSB 中,明度越大,颜色越鲜艳,明度越小颜色越黑。
我们可以想象一下,HSL 和 HSB 都把 RGB 的颜色投影到一个圆柱体上,饱和度s为半径,明度v或者亮度l为高度,截面不同扇形区域对应不同的色相,越靠近中心颜色越灰。HSL 中,顶部和底部是白和黑,而 HSB 底部是黑色,顶部是各色相最鲜艳的颜色。
RGB 到 HSL、HSB 的转换:
记 RGB 颜色为(r,g,b), 都是[0,1]之间的实数,首先
max=max(r,g,b)min=min(r,g,b)
到 HSL:
h=⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧0∘,max=min60∘×max−ming−b,max=r and g>b60∘×max−minb−r+120∘,max=g60∘×max−minr−g+240∘,max=b60∘×max−ming−b+360∘,max=r and g<b
s=⎩⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎧0,l=0 or max=min2lmax−min,0<l<0.52−2lmax−min,l>0.5
l=2max+min
HSL 和 HSB 有同样的色相定义,饱和度s和明度v的定义则不同:
s=⎩⎪⎨⎪⎧0,max=0maxmax−min,elsev=max
HWB
HWB 是 RGB 的柱坐标表示形式,类似于 HSL 和 HSB,HWB 的设计初衷是让人类使用起来更加直观,并且计算速度稍快一些。它是由 HSB 发展而来的。HWB 由色相 Hue、白度 Whiteness、黑度 Blackness 组成。直观上,这代表我们选了一种颜色,可以通过往里面加黑色和白色改变它的深浅明暗。
RGB 到 HWB 的转换:
色相h的计算同 HSL、HSB。
w=min(r,g,b)b=1−max(r,g,b)
HSB 到 HWB 的转换:
色相h的计算同 HSL、HSB。
w=(1−s)vb=1−v