TA工具箱首页 / 工具教程

色彩空间转换:Linear、sRGB 与 Gamma 校正教程

2026-08-24

引言

在计算机图形学中,色彩空间转换至关重要。sRGB 是标准显示色彩空间,具有非线性的 gamma 曲线;而物理计算通常在线性空间进行。正确转换可以避免颜色偏差和光照错误。本教程将指导你进行转换。

理解基本概念

  • **sRGB**:标准红绿蓝色彩空间,广泛用于显示器、图像文件。其值经过 gamma 编码,约等于 2.2 的幂函数。
  • **线性空间**:光强度与数值成正比,用于物理渲染和光照计算。
  • **Gamma 校正**:将线性值转换为 sRGB 供显示,或反向转换。

使用 Photoshop 转换

查看和分配色彩空间

  1. 打开图片,选择“编辑” > “颜色设置”。
  2. 在“工作空间”中设置 RGB 为 sRGB 或自定义线性。
  3. 要转换图片,使用“编辑” > “转换为配置文件”,选择目标色彩空间。
  4. 手动 gamma 调整

    • 使用“图像” > “调整” > “色阶”或“曲线”,将中间调调整为 gamma 2.2(提亮)或 1/2.2(压暗)。

    使用 Python 进行转换

    使用 Pillow 和 NumPy

    安装库:

    ```bash

    pip install Pillow numpy

    ```

    转换函数示例:

    ```python

    import numpy as np

    from PIL import Image

    def srgb_to_linear(img):

    arr = np.array(img, dtype=np.float32) / 255.0

    mask = arr <= 0.04045

    arr[mask] = arr[mask] / 12.92

    arr[~mask] = ((arr[~mask] + 0.055) / 1.055) ** 2.4

    return arr

    def linear_to_srgb(arr):

    mask = arr <= 0.0031308

    arr[mask] = arr[mask] * 12.92

    arr[~mask] = 1.055 * (arr[~mask] ** (1/2.4)) - 0.055

    return (arr * 255).astype(np.uint8)

    ```

    使用着色器转换

    在 GLSL 或 HLSL 中,GPU 可以自动处理 sRGB 纹理采样,但手动转换也常见。

    GLSL 函数

    ```glsl

    vec3 srgb_to_linear(vec3 c) {

    return mix(c / 12.92, pow((c + 0.055) / 1.055, vec3(2.4)), step(0.04045, c));

    }

    vec3 linear_to_srgb(vec3 c) {

    return mix(c * 12.92, 1.055 * pow(c, vec3(1.0/2.4)) - 0.055, step(0.0031308, c));

    }

    ```

    使用 OpenCV

    OpenCV 通常假设图像为 BGR 顺序,且默认不进行 gamma 校正。可以使用 `cvtColor` 配合查找表。

    实际应用

    • **纹理导入**:在 Unity 或 Unreal 中,标记纹理为 sRGB(颜色贴图)或 Linear(法线、粗糙度等)。
    • **渲染管线**:确保光照计算在线性空间,输出前转换为 sRGB。

    注意事项

    • **精度**:使用浮点缓冲存储线性数据,避免 8 位精度损失。
    • **一致性**:项目中统一色彩空间管理,避免混合。
    • **浏览器**:Canvas 和 WebGL 需正确处理色彩空间。

    总结

    掌握色彩空间转换是图形开发的基础。通过正确设置图像处理软件、使用代码转换或在着色器中处理,可以确保颜色准确。

常见问题

sRGB 和线性空间有什么区别?

sRGB 经过 gamma 编码,更符合人眼感知,存储效率高;线性空间数值与光强度成正比,适合物理计算。

如何判断我的图片是 sRGB 还是线性?

通常颜色贴图是 sRGB,数据贴图(如法线、粗糙度)是线性。检查图片元数据或来源软件设置。

在 Unity 中如何设置纹理色彩空间?

在纹理导入设置中,将颜色贴图的 sRGB 选项勾选,数据贴图取消勾选。项目设置中可全局配置色彩空间。

为什么我的颜色在引擎中看起来过暗或过亮?

可能是色彩空间不匹配。检查纹理的 sRGB 标记,以及渲染输出的 gamma 设置。

Web 开发中需要考虑色彩空间转换吗?

是的,Canvas 和 WebGL 默认使用 sRGB,如果进行物理渲染需要手动转换为线性空间。