参考原文:https://www.zhihu.com/question/22077462/answer/342570140

1.RGB原理

RGB色彩模式是工业界的一种颜色标准,是通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,是目前运用最广的颜色系统之一。

RGB是从颜色发光的原理来设计定的,通俗点说它的颜色混合方式就好像有红、绿、蓝三盏灯,当它们的光相互叠合的时候,色彩相混,而亮度却等于两者亮度之总和,越混合亮度越高,即加法混合。
红、绿、蓝三个颜色通道每种色各分为256阶亮度,在0时“灯”最弱——是关掉的,而在255时“灯”最亮。当三色灰度数值相同时,产生不同灰度值的灰色调,即三色灰度都为0时,是最暗的黑色调;三色灰度都为255时,是最亮的白色调。

对一种颜色进行编码的方法统称为“颜色空间”或“色域”。用最简单的话说,世界上任何一种颜色的“颜色空间”都可定义成一个固定的数字或变量。RGB(红、绿、蓝)只是众多颜色空间的一种。采用这种编码方法,每种颜色都可用三个变量来表示-红色绿色以及蓝色的强度。记录及显示彩色图像时,RGB是最常见的一种方案。
43 封私信  81 条消息 色彩空间中的 HSL、HSV、HSB 有什么区别? - 知乎.jpg
RGB在编码时也会有多种组合方式,在WPU中使用的是RGB24格式,使用24位来表示一个像素,RGB分量都用8位表示,取值范围为0-255。

2.HLS原理

HSL色彩模式是工业界的另一种颜色标准,是通过对色相(H)、饱和度(S)、明度(L)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,HSL即是代表色相,饱和度,明度三个通道的颜色。

HSL的H(hue)分量,代表的是人眼所能感知的颜色范围,这些颜色分布在一个平面的色相环上,取值范围是0°到360°的圆心角,每个角度可以代表一种颜色。色相值的意义在于,我们可以在不改变光感的情况下,通过旋转色相环来改变颜色。在实际应用中,我们需要记住色相环上的六大主色,用作基本参照:360°/0°红、60°黄、120°绿、180°青、240°蓝、300°洋红,它们在色相环上按照60°圆心角的间隔排列。
43 封私信  81 条消息 色彩空间中的 HSL、HSV、HSB 有什么区别? - 知乎.jpg

HSL的S(saturation)分量,指的是色彩的饱和度,它用0%至100%的值描述了相同色相、明度下色彩纯度的变化。数值越大,颜色中的灰色越少,颜色越鲜艳,呈现一种从灰度到纯色的变化。
43 封私信  81 条消息 色彩空间中的 HSL、HSV、HSB 有什么区别? - 知乎.jpg

HSL的L(lightness)分量,指的是色彩的明度,作用是控制色彩的明暗变化。它同样使用了0%至100%的取值范围。数值越小,色彩越暗,越接近于黑色;数值越大,色彩越亮,越接近于白色。
43 封私信  81 条消息 色彩空间中的 HSL、HSV、HSB 有什么区别? - 知乎.jpg

3.HSB原理

HSB又称HSV,表示一种颜色模式:在HSB模式中,H(hues)表示色相,S(saturation)表示饱和度,B(brightness)表示亮度HSB模式对应的媒介是人眼。

色相(H,hue):在0~360°的标准色轮上,色相是按位置度量的。在通常的使用中,色相是由颜色名称标识的,比如红、绿或橙色。黑色和白色无色相。
饱和度(S,saturation):表示色彩的纯度,为0时为灰色。白、黑和其他灰色色彩都没有饱和度的。在最大饱和度时,每一色相具有最纯的色光。取值范围0~100%。
亮度(B,brightness或V,value):是色彩的明亮度。为0时即为黑色。最大亮度是色彩最鲜明的状态。取值范围0~100%。

三个指标如果综合在一起看的话,可以用下图来显示:
43 封私信  81 条消息 色彩空间中的 HSL、HSV、HSB 有什么区别? - 知乎.png
43 封私信  81 条消息 色彩空间中的 HSL、HSV、HSB 有什么区别? - 知乎.png

HSL 和 HSV 二者都把颜色描述在圆柱体内的点,这个圆柱的中心轴取值为自底部的黑色到顶部的白色而在它们中间是的灰色,绕这个轴的角度对应于“色相”,到这个轴的距离对应于“饱和度”,而沿着这个轴的距离对应于“亮度”,“色调”或“明度”。

这两种表示在用目的上类似,但在方法上有区别。二者在数学上都是圆柱,但 HSV(色相,饱和度,明度)在概念上可以被认为是颜色的倒圆锥体(黑点在下顶点,白色在上底面圆心),HSL在概念上表示了一个双圆锥体和圆球体(白色在上顶点,黑色在下顶点,最大横切面的圆心是半程灰色)。
注意尽管在HSL 和 HSV 中“色相”指称相同的性质,它们的“饱和度”的定义是明显不同的。

HSL 类似于 HSV。对于一些人,HSL 更好的反映了“饱和度”和“亮度”作为两个独立参数的直觉观念,但是对于另一些人,它的饱和度定义是错误的,因为非常柔和的几乎白色的颜色在 HSL 可以被定义为是完全饱和的。对于 HSV 还是 HSL 更适合于人类用户界面是有争议的。

43 封私信  81 条消息 色彩空间中的 HSL、HSV、HSB 有什么区别? - 知乎.jpg43 封私信  81 条消息 怎样用 rgb 三元组理解色相、亮度和饱和度? - 知乎.jpg

W3CCSS3 规定声称“HSL 的优点是它对称于亮与暗(HSV 就不是这样)…”,这意味着:
· 在 HSL 中,饱和度分量总是从完全饱和色变化到等价的灰色(在 HSV 中,在极大值 V 的时候,饱和度从全饱和色变化到白色,这可以被认为是反直觉的)。
· 在 HSL 中,亮度跨越从黑色过选择的色相到白色的完整范围(在 HSV 中,V 分量只走一半行程,从黑到选择的色相)。


4.HLS、HSB与RGB的关系

综上所述,三种不同的色彩系统,只是描述色彩的维度不同,因此它们之间是可以互相转换的。在WPU的原有设计框架中,是根据HLS或者HSB(推测?)的数值来推算RGB的过程。

我们先从理论上来分析HLS、HSB和 RGB之间的关系。

下面这个变换坐标系的描述,直接引用自@无名诗的答案无名诗:怎样用 rgb 三元组理解色相、亮度和饱和度?

4.1 明度(Lightness)

首先解释最好理解的明度(Lightness):

我们引入一个三维直角坐标系,三个坐标轴分别代表R、G、B的数量。由于此数值有限,所以取值范围会在立体空间里形成一个正方体。任何一个RGB颜色制式中的色彩取值,都会对应到这个立方体内的一点。

43 封私信  81 条消息 怎样用 rgb 三元组理解色相、亮度和饱和度? - 知乎.jpg

现在我们从原点(0,0,0)到对角的顶点(255,255,255)连出一条直线,也就是一条体对角线。这条对角线就可以说是一条明度轴了,原点最暗,另一端最亮。而任何一个颜色对应到的一点在这条体对角线上的“投影”,就是这个颜色的明度(Lightness)。靠近原点就越暗,靠近(255,255,255)就越亮。

4.2 饱和度(Saturation)和色相(Hue)

然后我们需要再引入一个极坐标系,来解释饱和度(Saturation)色相(Hue)

43 封私信  81 条消息 怎样用 rgb 三元组理解色相、亮度和饱和度? - 知乎.jpg

极坐标系由角度轴和距离轴构成。把红蓝绿三个颜色分别置于角度轴的0°、120°、240°,此时色相就被角度轴来表示。从图中也可以看到,从0°到120°中间的区域就是橙色、黄色这些红色到绿色的过渡颜色,其他区域也是同理,每个色相都映射一个角度。而让原点的颜色为灰色,越往外颜色越鲜艳,则距离轴代表的就是饱和度。

这里我们再借助向量,把R、G、B映射到角度轴,R、G、B的数值为距离轴,绘制三个向量。假设我们现在有一个颜色,R=100,G=150,B=200,那我们就在极坐标中,画一个坐标为(100,0°)的向量,一个坐标为(150,120°)的向量,一个坐标为(200,240°)的向量。

43 封私信  81 条消息 怎样用 rgb 三元组理解色相、亮度和饱和度? - 知乎.jpg
然后把这三个向量做向量的加法,最终会落在一个点上。这个点的角度轴数值就是此颜色的色相,而距离轴数值就是它的饱和度了。蓝色箭头终点即为此色,色相210°,饱和度50%。

4.3 亮度(Brightness)

不过,这个极坐标是一个二维坐标,不能表示RGB颜色制式中的所有颜色,只能解释色相和饱和度。如何使其表示所有颜色?我们需要再添加一个纵轴,变成了这样:

43 封私信  81 条消息 怎样用 rgb 三元组理解色相、亮度和饱和度? - 知乎.jpg
这里添加的这根纵轴就是亮度(Brightness)。而这个模型就是HSB模型/HSV模型。此外,还有个HSL模型,就是把Brightness轴替换成Lightness轴,替换后其顶层所有颜色都为白色。

顶层的纵坐标是255,白色是255,红色也一样是255,顶层大家的“光的量”Brightness都是最大值。底层的坐标是0,白色是0,红色也是0,所以说亮度是表示单个颜色的含量的。但是红色在上一个三维直角模型中,其投影并未到明度轴的顶点,其三数值平均值只有255/3=85,远不到最大值255,“与白色的相近程度”还明显差得很远。

图中,顶层是白色和最鲜艳的颜色,底层则清一色是黑色,想到了什么?没错,Photoshop的调色板。Photoshop的调色板也是基于HSV模型设计的,色相轴被独立出来在右侧,亮度和饱和度在二维坐标中供调制。

因此也有人用下面这个色环模型来表示HLS模型:

43 封私信  81 条消息 怎样用 rgb 三元组理解色相、亮度和饱和度? - 知乎.jpg

5.RGB到HLS的过程

设 (r, g, b) 分别是一个颜色的红、绿和蓝坐标,它们的值是在 0 到 1 之间的实数。设 max 等价于 r, g 和 b 中的最大者。设 min 等于这些值中的最小者。要找到在 HSL 空间中的 (h, s, l) 值,这里的 h ∈ [0, 360)是角度的色相角,而 s, l ∈ [0,1] 是饱和度和亮度,计算为:
image.png

h 的值通常规范化到位于 0 到 360°之间。而 h = 0 用于 max = min 的(就是灰色)时候而不是留下 h 未定义。
HSL 和 HSV 有同样的色相定义,但是其他分量不同。HSV 颜色的 s 和 v 的值定义如下:
image.png

6.HLS到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 的时候,可以使用下列过程:[[1]

image.png
对于每个颜色向量 Color =(ColorR, ColorG, ColorB) = (r, g, b),
image.png

7.HSB到RGB的过程

类似的,给定在 HSV 中
(h, s, v) 值定义的一个颜色,带有如上的 h,和分别表示饱和度和明度的 s和 v 变化于 0 到 1 之间,在 RGB 空间中对应的
(r, g, b) 三原色可以计算为:
image.png