做照片编辑 APP?你得先搞懂色彩空间管理

你有没有遇到过这种情况:在手机上修了一张照片,颜色调得特别好看,结果发给朋友一看,他那边颜色完全不一样?或者从相机导入一张 Adobe RGB 的照片,到 APP 里颜色变得灰蒙蒙的?

这背后的原因就是"色彩空间"不同。简单说,色彩空间就是"颜色的坐标系"。不同的设备、不同的标准,对"红色"的定义范围是不一样的。如果你不做色彩空间管理,APP 在处理图片时就会"各说各话",颜色当然对不上。

HarmonyOS 提供了 colorSpaceManager 这个模块,专门帮你管理色彩空间。今天我们来看看,做一个照片编辑 APP 时,怎么用它来保证颜色的一致性。

先导入模块

import { colorSpaceManager } from '@kit.ArkGraphics2D';

这行不用多说,所有用到色彩管理的地方都需要先导入它。

认识色彩空间类型:ColorSpace 枚举

在开始写代码之前,你得先了解一下有哪些常见的色彩空间。ColorSpace 枚举定义了所有支持的类型:

  • SRGB (值为 4):这是最通用的色彩空间,也是系统默认的。大部分手机屏幕、网页用的都是它。如果你不确定用什么,选 SRGB 就对了。
  • DISPLAY_P3 (值为 3):苹果带头推广的广色域标准,现在大部分中高端手机屏幕都支持。它比 SRGB 能显示更多颜色,尤其是红色和绿色更鲜艳。
  • ADOBE_RGB_1998 (值为 1):专业摄影和印刷领域常用,绿色范围特别广。如果你的 APP 要处理专业相机拍的照片,很可能需要支持它。
  • BT2020_HLG / BT2020_PQ (值为 9 / 10):这些是 HDR 视频用的色彩空间,能显示更亮、更丰富的颜色。做视频编辑类 APP 会用到。
  • LINEAR_SRGB / LINEAR_P3 / LINEAR_BT2020 (值为 24 / 23 / 25):线性色彩空间,没有经过 gamma 校正,适合做图像计算和渲染。

打个比方,SRGB 就像是普通话,大家都听得懂;DISPLAY_P3 像是方言,能表达更细腻的意思,但不是所有人都懂;而 Adobe RGB 像是专业术语,只有特定圈子的人才用。

创建一个标准色彩空间对象

最简单的用法就是创建一个已知类型的标准色彩空间。比如你的 APP 默认使用 SRGB:

try {
  let colorSpace = colorSpaceManager.create(colorSpaceManager.ColorSpace.SRGB);
} catch (err) {
  console.error(`Failed to create SRGB colorSpace. Cause: ` + JSON.stringify(err));
}

这里调用了 colorSpaceManager.create(),传入一个 ColorSpace 枚举值,它会返回一个 ColorSpaceManager 实例。这个实例就是你后续做色彩转换、获取色彩属性的基础。

注意两点:

  1. 不能用 UNKNOWNCUSTOM 来直接创建。这两个枚举值不是有效的色彩空间类型,如果你传进去会报错(错误码 18600001)。
  2. 记得用 try-catch 包起来。虽然创建标准色彩空间一般不会失败,但养成错误处理的习惯总是好的。

如果你要做广色域照片编辑,换成 DISPLAY_P3 就行:

let colorSpace = colorSpaceManager.create(colorSpaceManager.ColorSpace.DISPLAY_P3);

创建自定义色彩空间

有时候标准的色彩空间满足不了你的需求。比如你拿到一张用特殊相机拍的照片,它的色彩空间不在标准枚举里。这时候你可以用自定义方式创建:

try {
  let primaries: colorSpaceManager.ColorSpacePrimaries = {
    redX: 0.1,
    redY: 0.1,
    greenX: 0.2,
    greenY: 0.2,
    blueX: 0.3,
    blueY: 0.3,
    whitePointX: 0.4,
    whitePointY: 0.4
  };
  let gamma = 2.2;
  let colorSpace = colorSpaceManager.create(primaries, gamma);
} catch (err) {
  console.error(`Failed to create colorSpace with customized primaries and gamma. Cause: ` + JSON.stringify(err));
}

这里传了两个参数:

primaries(色域标准三原色):这是一个 ColorSpacePrimaries 对象,包含红、绿、蓝三原色和白色的坐标值。每个颜色用 (x, y) 两个坐标来描述它在色度图上的位置。这些数值通常是从相机的 ICC 配置文件里读出来的。

gamma(伽马值):控制亮度曲线的参数,通常为 2.2(这也是 SRGB 的标准 gamma 值)。不同的 gamma 值会让图片看起来亮度不一样。

在实际开发中,你很少需要手动填这些数值。更常见的做法是从图片的元数据中读取 ICC 配置文件,然后解析出这些参数。这里只是演示怎么创建。

查询色彩空间的基本属性

创建出色彩空间对象后,你可以查询它的各种属性。这在照片编辑 APP 里很有用——比如你想在 UI 上显示当前图片的色彩空间信息。

获取色彩空间类型名称:

try {
  let spaceName = colorSpace.getColorSpaceName();
  console.info(`spaceName: ` + spaceName.toString());
} catch (err) {
  console.error(`Failed to get colorSpace's name. Cause: ` + JSON.stringify(err));
}

这个方法返回一个 ColorSpace 枚举值。如果你之前创建的是 SRGB,这里就返回 4。你可以用它来判断当前图片用的是哪种色彩空间,然后决定是否需要做转换。

获取白点值:

try {
  let point = colorSpace.getWhitePoint();
  console.info(`point: ` + point.toString());
} catch (err) {
  console.error(`Failed to get white point. Cause: ` + JSON.stringify(err));
}

白点值返回一个 [x, y] 数组,表示这个色彩空间里"白色"的坐标。不同色彩空间对"白色"的定义是不一样的。比如 D65 白点(SRGB 和 Display P3 用的)和 D50 白点(印刷行业常用的)就不同。

获取 gamma 值:

try {
  let gamma = colorSpace.getGamma();
  console.info(`gamma: ` + gamma.toString());
} catch (err) {
  console.error(`Failed to get gamma. Cause: ` + JSON.stringify(err));
}

返回一个浮点数,就是这个色彩空间的 gamma 值。SRGB 的 gamma 大约是 2.2,但 SRGB 的转换函数其实不是标准的 gamma 曲线,而是一个分段函数,所以在做精确的颜色计算时要注意这个区别。

色彩空间创建方式

HarmonyOS 提供了两种创建色彩空间的方式,根据你的需求选择:

标准格式

特殊相机/自定义

需要创建色彩空间

图片来源?

使用枚举创建

使用参数创建

SRGB 通用标准

DISPLAY_P3 广色域

ADOBE_RGB 专业摄影

设置色域三原色 primaries

设置伽马值 gamma

create 创建实例

ColorSpaceManager 实例

实际场景:照片编辑 APP 的色彩管理流程

把这些 API 串起来,在一个照片编辑 APP 里,典型的使用流程是这样的:

  1. 导入照片时:读取照片的 ICC 配置文件,用 colorSpaceManager.create(primaries, gamma) 创建对应的色彩空间对象。如果照片是标准类型(比如 SRGB 或 Display P3),也可以直接用枚举创建。

  2. 编辑过程中:在 APP 内部统一使用一个色彩空间(通常是 SRGB 或 Display P3)来做滤镜、调色等操作。如果导入的照片色彩空间和内部不一致,需要做色彩空间转换。

  3. 导出照片时:根据用户选择的目标色彩空间,把编辑后的图片转换到目标色彩空间,然后写入文件。

  4. UI 显示时:用 getColorSpaceName() 获取当前图片的色彩空间类型,在界面上显示给用户,比如"当前色彩空间:Display P3"。

照片编辑 APP 的色彩管理流程图

下面是照片编辑 APP 中色彩管理的典型工作流程:

不一致

一致

导入照片

读取 ICC 配置文件

创建源色彩空间

色彩空间是否一致?

执行色彩空间转换

直接处理

统一使用内部色彩空间

应用滤镜/调色

导出照片

转换到目标色彩空间

保存文件

UI 显示色彩空间信息

小结

colorSpaceManager 这个模块虽然 API 不多,但它是做任何颜色相关功能的基础。掌握了创建标准色彩空间、创建自定义色彩空间、查询属性这三个核心操作,你就能在照片编辑 APP 里正确处理不同来源的图片,避免颜色失真的问题。

记住一个原则:在你的 APP 内部,尽量统一使用一种色彩空间做处理,只在输入和输出时做转换。这样可以最大程度地减少颜色精度的损失。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐