随着对 OKLCH 颜色模型的支持日益增长,理解它与无处不在的 RGB 模型之间的关系也变得越来越重要。虽然 OKLCH 提供了卓越的感知均匀性和对广色域颜色的访问,但我们的屏幕(大多数)仍然使用 RGB 子像素工作。
在这篇文章中,我们将探索将 OKLCH 颜色转换为大多数网络设备使用的标准 sRGB 空间的数学旅程。
在我们深入研究数学之前,您可以亲自尝试转换过程!调整下面的亮度 (Lightness)、色度 (Chroma) 和色相 (Hue) 滑块,看看它们如何映射到 RGB 十六进制代码。
oklch(60% 0.15 250)#2784D5 / rgb(39, 132, 213)
将 OKLCH 转换为 RGB 不是一步完成的;它涉及跨越不同色彩空间的一系列变换。
首先,我们需要将圆柱形的 OKLCH 坐标(亮度、色度、色相)转换回笛卡尔 OKLab 坐标 (L, a, b)。
- L 保持不变。
- a (绿-红) 使用余弦计算:a=C×cos(H)
- b (蓝-黄) 使用正弦计算:b=C×sin(H)
(注意:确保 H 在这些计算中使用弧度。)
接下来,我们从感知的 OKLab 空间移动到“线性” RGB 空间。这个变换包含三个子步骤:
我们首先使用特定的矩阵将 L, a, b 坐标变换到中间的 LMS 域:
L′M′S′=1110.3963377774−0.1055613458−0.08948417750.2158037573−0.0638541728−1.2914855480Lab
OKLab 模型使用立方根非线性。为了回到线性光强度,我们必须将结果 LMS 值立方:
LlinMlinSlin=(L′)3=(M′)3=(S′)3
最后,我们使用另一个矩阵变换将这些线性 LMS 值转换为线性 RGB:
RlinGlinBlin=4.0767416621−1.2684380046−0.0041960863−3.30771159132.6097574011−0.70341861470.2309699292−0.34131939651.7076147010LlinMlinSlin
最后,大多数屏幕需要“Gamma 校正”信号。这是因为人眼对暗色调比对亮色调更敏感。
标准 sRGB 转换使用传递函数:
- 如果值非常小 (≤0.0031308),乘以 12.92。
- 否则,将其提升到 (1/2.4) 的幂并应用缩放偏移。
VsRGB=1.055×Vlinear(1/2.4)−0.055
这最后一步给了我们熟悉的 0-255 值(缩放后),用于红、绿和蓝。
让我们通过这个流程追踪 oklch(60% 0.15 250):
-
到 OKLab:
- L=0.6
- H=250∘≈4.36 rad
- a=0.15×cos(4.36)≈−0.051
- b=0.15×sin(4.36)≈−0.141
-
到线性 RGB (矩阵变换后):
- Rlin≈0.021
- Glin≈0.229
- Blin≈0.667
-
到 sRGB (Gamma 校正后):
- R≈39
- G≈132
- B≈213
- Hex:
#2784D5
理解这些转换突显了简单的 CSS 颜色声明背后隐藏的复杂性。虽然现代浏览器会自动处理这些,但了解数学原理能让我们更深入地体会数字色彩科学的精确性。