当前位置: 首页 > news >正文

鸿蒙开发-想在多线程间共享色彩配置?sendableColorSpaceManager怎么用

多线程处理图片?色彩管理器也要能"共享"

上一篇我们聊了colorSpaceManager,它能帮你创建和管理色彩空间。但有一个问题:如果你的照片编辑 APP 需要在后台线程处理大量图片(比如批量滤镜、批量导出),普通的colorSpaceManager创建出来的对象是不能跨线程传递的。

为什么呢?因为在 ArkTS 的并发模型里,不同线程之间的对象默认是隔离的,你不能直接把一个线程里创建的对象传给另一个线程用。如果你尝试这么做,运行时会报错。

HarmonyOS 提供了sendableColorSpaceManager这个模块来解决这个问题。它创建出来的色彩管理器实现了ISendable接口,可以在主线程、TaskPool、Worker 等并发实例之间传递,而且传递的方式是引用传递——也就是说,多个线程共享同一个对象,修改会互相影响。

导入模块

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

注意这里同时导入了两个模块。因为sendableColorSpaceManager的参数类型(比如ColorSpace枚举、ColorSpacePrimaries接口)都定义在colorSpaceManager里,所以两个都要导入。

普通版与可共享版对比

下面是两种色彩管理器的使用场景对比:

单线程

多线程

需要色彩管理器

使用场景?

colorSpaceManager

sendableColorSpaceManager

照片编辑预览

滤镜实时预览

色彩空间显示

TaskPool 批量处理

Worker 后台导出

多线程色彩转换

普通 Array 返回

ISendable 接口

collections.Array 返回

创建标准可共享色彩空间

跟普通版本的用法几乎一样,只是把colorSpaceManager.create换成了sendableColorSpaceManager.create

import{colorSpaceManager,sendableColorSpaceManager}from'@kit.ArkGraphics2D';letcolorSpace:sendableColorSpaceManager.ColorSpaceManager;colorSpace=sendableColorSpaceManager.create(colorSpaceManager.ColorSpace.SRGB);

这里有几个细节值得注意:

  1. 返回类型不同:普通版返回的是colorSpaceManager.ColorSpaceManager,而这里返回的是sendableColorSpaceManager.ColorSpaceManager。虽然名字一样,但它们是不同的类型。可共享版本实现了ISendable接口,所以能跨线程传递。

  2. 参数来源相同:色彩空间的枚举值ColorSpace还是来自colorSpaceManager,可共享版本并没有重新定义一套枚举。

  3. UNKNOWN 和 CUSTOM 同样不能直接创建:跟普通版一样,这两个枚举值不能传给create方法。

创建自定义可共享色彩空间

如果你需要处理自定义色彩空间的照片,也可以创建自定义的可共享色彩管理器:

import{colorSpaceManager,sendableColorSpaceManager}from'@kit.ArkGraphics2D';letcolorSpace:sendableColorSpaceManager.ColorSpaceManager;letprimaries: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};letgamma:number=2.2;colorSpace=sendableColorSpaceManager.create(primaries,gamma);

跟普通版完全一样的参数,只是调用的是sendableColorSpaceManager.create。创建出来的对象同样继承了ISendable,可以在多线程间共享。

查询属性:跟普通版一样的方法

可共享版本的ColorSpaceManager实例提供了跟普通版一样的属性查询方法,但 API 签名稍有不同。

获取色彩空间类型:

letspaceName:colorSpaceManager.ColorSpace=colorSpace.getColorSpaceName();

注意返回类型直接用了colorSpaceManager.ColorSpace,没有 try-catch 的示例。在实际使用中,建议你还是加上错误处理。

获取白点值:

import{collections}from'@kit.ArkTS';letpoint:collections.Array<number>=colorSpace.getWhitePoint();

这里有个小区别:可共享版本返回的是collections.Array<number>,而不是普通的Array<number>collections.Array是 ArkTS 提供的可共享数组类型,同样能在多线程间传递。使用时你需要额外导入collections模块。

获取 gamma 值:

letgamma:number=colorSpace.getGamma();

这个跟普通版完全一样,返回一个浮点数。

多线程批量处理流程

下面是使用 sendableColorSpaceManager 进行批量图片处理的典型流程:

主线程

创建可共享色彩空间

传递给 TaskPool

工作线程1

工作线程2

工作线程3

处理图片批次1

处理图片批次2

处理图片批次3

色彩空间转换

导出处理结果

实际场景:后台批量处理图片的色彩管理

想象一下这个场景:你的照片编辑 APP 有一个"批量导出"功能,用户选了 100 张照片,要全部转换成 SRGB 色彩空间后导出。这个过程如果在主线程做,UI 会卡死。所以你要用 TaskPool 来做。

使用sendableColorSpaceManager的流程是这样的:

在主线程创建可共享的色彩空间对象:

import{colorSpaceManager,sendableColorSpaceManager}from'@kit.ArkGraphics2D';// 创建一个 SRGB 色彩空间,用于批量导出lettargetColorSpace=sendableColorSpaceManager.create(colorSpaceManager.ColorSpace.SRGB);

把对象传给 TaskPool 的工作线程:

因为targetColorSpace实现了ISendable接口,你可以直接把它作为参数传给 TaskPool 的任务。在工作线程里,你可以直接使用这个对象来做色彩空间转换,不需要重新创建。

在工作线程里使用:

工作线程拿到这个对象后,可以调用getColorSpaceName()来确认目标色彩空间类型,然后对每张图片做转换。

什么时候该用可共享版本?

简单说,如果你的色彩管理器只在主线程用,就用普通的colorSpaceManager;如果需要在多个线程间共享,就用sendableColorSpaceManager

具体来说:

  • 单线程场景:普通的照片编辑、滤镜预览、色彩空间显示等,用colorSpaceManager就够了。
  • 多线程场景:批量图片处理、后台导出、TaskPool/Worker 中的色彩转换等,必须用sendableColorSpaceManager

性能方面,可共享版本因为要支持跨线程引用传递,可能会有轻微的额外开销。但对于色彩管理这种操作频率不高的场景,这个开销完全可以忽略。

小结

sendableColorSpaceManager本质上就是colorSpaceManager的多线程安全版本。它的 API 设计几乎一模一样,区别就是创建出来的对象可以跨线程共享。如果你的 APP 有多线程处理图片的需求,记得用它来替代普通的色彩管理器。

最后提醒一下:因为是引用传递,多个线程共享同一个对象,所以如果你在一个线程里修改了对象的状态(虽然目前的 API 都是只读的),其他线程会立即看到变化。在设计并发逻辑时要注意这一点。

http://www.cnnetsun.cn/news/2681775.html

相关文章:

  • 如何快速配置Python票务助手:面向新手的完整指南
  • 告别繁琐脚本!用CANoe AutoSequence可视化插件5分钟搞定自动化测试(附VisualSequence保姆级教程)
  • 具身智能研究现状与未来前景(四):具身导航——从几何路径规划到语义目标驱动的自主移动
  • 别再只显示数字了!玩转高德地图MarkerCluster:用权重实现动态业务图标与聚合策略
  • 保姆级教程:用u-center配置u-blox ZED-F9P的RTK基站与移动站(附避坑指南)
  • 5分钟掌握OpCore Simplify:黑苹果OpenCore配置从入门到精通
  • Python之encryptech包语法、参数和实际应用案例
  • 炉石传说HsMod终极指南:55+功能增强与高级游戏体验优化方案
  • 终极美化指南:5分钟打造你的专属foobar2000音乐播放器界面
  • AI Agent Harness Engineering 幻觉问题根源:从模型、数据到Prompt的全方位解析
  • 安卓手机上跑得动的人体识别+关节定位演示APP(含CPU/GPU双加速)
  • Snowflake Arctic-Embed-L OpenMind长文本处理方案:突破512 token限制的终极技巧
  • french_emotion_camembert vs 传统方法:为什么82.95%准确率的它更适合法语NLP任务
  • 别再手动调参了!用Matlab搞定双目相机标定,附Blender仿真数据与完整代码
  • 告别地形拉伸!在UE4/UE5中手把手实现三方向映射纹理(附Unity URP版Shader源码)
  • 避开这些坑!用LSTM预测股价时,你的数据预处理做对了吗?(附实战代码)
  • 金融数据分析实战:用Python Winsorize处理股票收益率极端值(附完整代码与NaN处理技巧)
  • [智能体-199]:编排的本质:任务分解与调度,和项目管理同源同构
  • 098.硬件感知的神经架构搜索(NAS)简介:从一次深夜调优说起
  • 102、【Agent】【OpenCode】task 工具提示词(examples)
  • Adobe GenP 3.0完整指南:一键破解Adobe Creative Cloud全系列软件
  • Django+Vue校园二手物品交易系统源码+论文
  • 别再硬编码了!用ShaderGraph为你的URP模型动态“穿”上发光线框(附完整节点图)
  • 综合实验2
  • 别再为OneDrive账号切换烦恼了!一个Windows用户搞定多个个人版同步(附权限设置避坑指南)
  • 指针引发的内存问题-----无用的知识又增加了
  • C语言内存分配,栈区、堆区、全局区、常量区和代码区都是什么
  • Cortex-A7 L2缓存电源管理机制与优化策略
  • VMware虚拟机里给正点原子ATK-DLRK3568烧录镜像,保姆级避坑指南(Ubuntu 20.04)
  • Skill 是什么?——AI Agent 的“技能包“