HarmonyOS APP实战-画图APP - 第10篇:色彩管理功能 HarmonyOS APP实战-画图APP - 第10篇色彩空间转换与HDR支持1. 开篇在上一篇中我们实现了智能取色与色板生成功能——通过ohos.effectKit的ColorPicker提取图像主色并动态生成五色色板供用户快速选择。用户点击画布任意区域即可获取该区域主色色板同步更新大大提升了取色效率。然而显示设备的色彩能力千差万别。目前 APP 绘制的颜色均基于 sRGB 色域而越来越多的设备支持 Display P3、BT.2020 等更广色域甚至支持 HDR高动态范围。为了充分利用硬件能力让画作色彩更加鲜艳、明暗对比更真实我们需要集成色彩空间管理能力。本篇将集成ohos.graphics.colorSpaceManager实现色彩空间转换并利用ohos.graphics.hdrCapability检测设备 HDR 能力在 APP 中添加 HDR 模式开关使画布能够输出 HDR 色彩。2. 核心实现2.1 基础配置 – 导入模块与权限声明在ets/entryability/EntryAbility.ets中或工具模块中导入必要的 API。由于色彩空间管理不涉及敏感权限无需额外授权但需要确保 API 版本兼容推荐 API 12。// utils/ColorManager.etsimport{colorSpaceManager}fromkit.ArkGraphics2D;// ohos.graphics.colorSpaceManagerimport{hdrCapability}fromkit.ArkGraphics2D;// ohos.graphics.hdrCapabilityimport{BusinessError}fromkit.BasicServicesKit;关键点说明colorSpaceManager提供create(colorSpaceName: colorSpace.ColorSpace)等方法创建色域对象并可获取色域属性。hdrCapability提供isHdrSupported()方法检测当前设备是否支持 HDR 显示。所有导入需在module.json5中确保已依赖kit.ArkGraphics2D默认包含。2.2 核心逻辑 – ColorManager 类与 HDR 检测编写ColorManager工具类封装色彩空间创建、颜色转换、HDR 能力判断逻辑。该类将被上层页面调用实现画布着色空间切换。// utils/ColorManager.etsexportclassColorManager{// 当前使用的色域对象privatecurrentColorSpace:colorSpaceManager.ColorSpace|nullnull;// 是否支持 HDRprivate_isHdrSupported:booleanfalse;constructor(){this.initHdrCheck();}/** * 检测设备 HDR 能力 */privateinitHdrCheck():void{try{this._isHdrSupportedhdrCapability.isHdrSupported();console.info(HDR 支持情况:,this._isHdrSupported);}catch(err){console.error(HDR 能力检测失败:,(errasBusinessError).message);this._isHdrSupportedfalse;}}getisHdrSupported():boolean{returnthis._isHdrSupported;}/** * 获取指定色域名称对应的 ColorSpace 对象 * param name 色域名称如 DISPLAY_P3, SRGB, BT2020_HLG */getColorSpace(name:string):colorSpaceManager.ColorSpace|null{constcolorSpaceNamescolorSpaceManager.ColorSpace;// 根据字符串映射到枚举值若 API 支持constenumValue(colorSpaceNamesasRecordstring,number)[name];if(enumValueundefined){console.warn(不支持的色域:,name);returnnull;}try{returncolorSpaceManager.create(enumValueascolorSpaceManager.ColorSpace);}catch(err){console.error(创建色域失败:,(errasBusinessError).message);returnnull;}}/** * 将 RGBA 颜色值从源色域转换到目标色域 * param rgba [r,g,b,a] 0-255 * param srcSpace 源色域名称 * param dstSpace 目标色域名称 */convertColor(rgba:number[],srcSpace:string,dstSpace:string):number[]{constsrcthis.getColorSpace(srcSpace);constdstthis.getColorSpace(dstSpace);if(!src||!dst){console.warn(色域转换失败无法创建源或目标色域);returnrgba;}try{// 假设 colorSpaceManager 提供了 convert 方法文档示例 API// 实际 API 为 colorSpaceManager.convert(color: number[], src: ColorSpace, dst: ColorSpace)constconvertedcolorSpaceManager.convert(rgba,src,dst);returnconverted;}catch(err){console.error(色域转换失败:,(errasBusinessError).message);returnrgba;}}}关键点说明hdrCapability.isHdrSupported()返回布尔值需在try-catch中调用以防不支持。colorSpaceManager.create()参数为枚举值枚举定义在colorSpaceManager.ColorSpace中包含SRGB、DISPLAY_P3、BT2020_HLG等。颜色转换方法colorSpaceManager.convert()此处为假设的 API 名称实际需以官方文档为准若文档未提供convert则需另寻途径。根据 ArkGraphics 2D 简介colorSpaceManager 主要提供色域创建和属性获取颜色转换可能通过colorSpaceManager.transform()或手动矩阵计算。此处为演示逻辑实际实现时应参照官方 API 参考。为确保文章准确性我们将在下文使用文档明确支持的 API 进行色域切换而非转换单个颜色值。真实 API 说明截至 HarmonyOS NEXTohos.graphics.colorSpaceManager的核心能力是色域对象的创建与元数据获取并不直接提供颜色转换 API。颜色的实际转换需要结合 Canvas 的colorSpace属性或通过offlineImageProcessing实现。因此我们的ColorManager将主要管理画布色域设置而非单独转换颜色。修改ColorManager以使代码符合文档实际能力// utils/ColorManager.ets (修正版)import{colorSpaceManager}fromkit.ArkGraphics2D;import{hdrCapability}fromkit.ArkGraphics2D;exportclassColorManager{privatecurrentColorSpace:colorSpaceManager.ColorSpace|nullnull;private_isHdrSupported:booleanfalse;constructor(){this.checkHdr();}privatecheckHdr():void{try{this._isHdrSupportedhdrCapability.isHdrSupported();}catch(e){this._isHdrSupportedfalse;}}getisHdrSupported():boolean{returnthis._isHdrSupported;}/** * 根据色域名称获取 ColorSpace 对象 */getColorSpace(name:string):colorSpaceManager.ColorSpace|null{try{// 枚举映射constenumMap:Recordstring,number{SRGB:colorSpaceManager.ColorSpace.SRGB,DISPLAY_P3:colorSpaceManager.ColorSpace.DISPLAY_P3,BT2020_HLG:colorSpaceManager.ColorSpace.BT2020_HLG,BT2020_PQ:colorSpaceManager.ColorSpace.BT2020_PQ,};constenumValenumMap[name];if(enumValundefined)returnnull;returncolorSpaceManager.create(enumVal);}catch(err){console.error(getColorSpace error:,err);returnnull;}}/** * 设置当前画布使用的色域实际使用时需要将 ColorSpace 传给 Canvas 的 colorSpace 属性 */setCanvasColorSpace(ctx:CanvasRenderingContext2D,colorSpaceName:string):void{constcsthis.getColorSpace(colorSpaceName);if(cs){// CanvasRenderingContext2D 的 colorSpace 属性可赋值 ColorSpace 对象ctx.colorSpacecs;console.info(Canvas 色域切换为:,colorSpaceName);}}}关键点说明Canvas 的colorSpace属性可以直接接受colorSpaceManager.ColorSpace对象从而影响后续绘制的颜色渲染。hdrCapability.isHdrSupported()是ohos.graphics.hdrCapability的核心方法调用前需确保设备支持 HDR 显示如华为 Mate 60 Pro。色域枚举值随 API 版本可能变化需参考官方文档。2.3 完整模块 – HDRToggle 组件与画布页面集成创建HDRToggle组件作为工具栏上的一个开关按钮。点击后切换画布的色域sRGB ↔ Display P3并展示 HDR 标识。同时将ColorManager注入到画布页面DrawingBoard中实现色彩空间切换。// pages/HDRToggle.etsimport{ColorManager}from../utils/ColorManager;import{hdrCapability}fromkit.ArkGraphics2D;Componentexportstruct HDRToggle{// 从父组件传入的 Canvas 上下文privatecanvasContext:CanvasRenderingContext2D;privatecolorManager:ColorManagernewColorManager();StateisHdrMode:booleanfalse;StatedeviceSupportHdr:booleanthis.colorManager.isHdrSupported;build(){Row({space:8}){// HDR 模式开关Toggle({type:ToggleType.Switch,isOn:this.isHdrMode}).onChange((isOn:boolean){this.isHdrModeisOn;if(isOnthis.deviceSupportHdr){// 切换至 Display P3 色域宽色域this.colorManager.setCanvasColorSpace(this.canvasContext,DISPLAY_P3);}else{// 切回 sRGB 标准色域this.colorManager.setCanvasColorSpace(this.canvasContext,SRGB);}}).enabled(this.deviceSupportHdr)// 不支持 HDR 的设备禁用开关Text(this.isHdrMode?HDR 模式:标准模式).fontSize(14)// HDR 图标if(this.deviceSupportHdr){Image($r(app.media.ic_hdr)).width(20).height(20).objectFit(ImageFit.Contain)}else{Text(不支持HDR).fontSize(12).fontColor(Color.Gray)}}.padding(8).backgroundColor(#f0f0f0).borderRadius(8)}}在主画布页面pages/DrawingBoard.ets中引用HDRToggle并将 Canvas 上下文传入// pages/DrawingBoard.etsimport{HDRToggle}from./HDRToggle;// ...其他导入EntryComponentstruct DrawingBoard{privatesettings:RenderingContextSettingsnewRenderingContextSettings(true);privatecontext:CanvasRenderingContext2DnewCanvasRenderingContext2D(this.settings);build(){Column(){// 顶部工具栏Row(){// ...其他工具按钮画笔、形状等HDRToggle({canvasContext:this.context}).width(auto)}.width(100%).height(60).padding({left:8,right:8})// 画布区域Canvas(this.context).width(100%).layoutWeight(1).backgroundColor(Color.White).onReady((){// 默认使用 sRGBthis.context.colorSpacethis.colorManager.getColorSpace(SRGB);})}.width(100%).height(100%)}}关键点说明HDRToggle组件通过State响应式管理 HDR 模式状态切换时调用ColorManager.setCanvasColorSpace()直接修改 Canvas 的colorSpace属性。若设备不支持 HDRhdrCapability.isHdrSupported()返回 false开关被禁用并显示“不支持HDR”文本。需在resources/base/element中添加ic_hdr.svg图标或使用系统图标替代如$media(startIcon)。3. 运行验证编译运行 APP 到支持 HDR 的真机如 Mate 60 Pro 系列或平板。预期效果顶部工具栏出现 HDR 开关开关默认关闭显示“标准模式”。点击开关画布背景色无明显变化但后续绘制的图形如矩形、圆形、手绘笔画颜色会变得更鲜艳Display P3 色域比 sRGB 多覆盖约 25% 的颜色。在画布上绘制一笔红色原本 sRGB 下接近 #FF0000开启 HDR 模式后红色可能更明亮、更饱和。您可以通过之前第9篇的智能取色功能提取红色区域对比 RGB 值变化。若在不支持 HDR 的模拟器或旧设备上运行开关将变灰旁边显示“不支持HDR”。4. 小结与预告本篇实现了色彩空间转换与 HDR 支持核心产出ColorManager封装了ohos.graphics.colorSpaceManager和ohos.graphics.hdrCapability提供色域创建、Canvas 色域设置、HDR 能力检测。HDRToggle组件集成到工具栏可一键切换画布色域让画作在 HDR 设备上呈现更丰富的色彩。至此画图 APP 的图形效果处理能力从 sRGB 扩展到宽色域/HDR为专业绘画用户提供更大创作空间。下一篇将聚焦操作历史管理利用命令模式Command Pattern实现绘制操作的撤销与重做。我们将设计操作栈记录每一步绘制命令支持无限次撤销受内存限制并配套 UI 按钮。敬请期待