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

鸿蒙开发-想从图片里提取颜色?ColorPicker帮你搞定

想从照片里提取主题色ColorPicker 帮你搞定你有没有注意过很多 APP 的界面颜色会跟着当前显示的图片变比如音乐播放器的背景色会随着专辑封面变化天气 APP 的配色会跟着风景照片走。这种从图片里提取主色调的效果在 HarmonyOS 里用effectKit的ColorPicker就能实现。上一篇我们聊了 Filter滤镜链今天我们来看看effectKit的另一个主角——ColorPicker智能取色器。ColorPicker 能干什么简单说ColorPicker 可以从一张图片里看出它的主要颜色。它提供了好几种取色方式getMainColor提取图片的主色就是把整张图片缩小到 1 个像素那个像素的颜色。getLargestProportionColor提取占比最多的颜色。getTopProportionColors提取占比最多的前 N 种颜色。getHighestSaturationColor提取饱和度最高的颜色最鲜艳的那个。getAverageColor提取平均颜色。isBlackOrWhiteOrGrayColor判断某个颜色是不是黑白灰。这些方法各有各的用处我们一个一个来看。下面是 ColorPicker 的整体使用流程读取图片创建 PixelMapcreateColorPicker 创建取色器选择取色方式getMainColor: 提取主色getTopProportionColors: 提取前N种颜色getHighestSaturationColor: 最鲜艳颜色getAverageColor: 平均颜色获取 Color 对象将颜色用于 UI 主题/背景等创建 ColorPicker和 Filter 一样ColorPicker 也需要先有一个 PixelMap。创建方式也很像import{image}fromkit.ImageKit;import{effectKit}fromkit.ArkGraphics2D;import{BusinessError}fromkit.BasicServicesKit;constcolornewArrayBuffer(96);letopts:image.InitializationOptions{editable:true,pixelFormat:3,size:{height:4,width:6}}image.createPixelMap(color,opts).then((pixelMap){effectKit.createColorPicker(pixelMap).then(colorPicker{console.info(Succeeded in creating colorPicker.);}).catch((err:BusinessError){console.error(Failed to create colorPicker. Code:${err.code}, message:${err.message});})})这里有几个细节值得说一下createColorPicker返回的是 Promise和createEffect返回 Filter不同创建 ColorPicker 是异步的。可能是因为取色算法需要一些计算时间所以设计成了异步接口。错误处理既然是 Promise就有 reject 的可能。记得用.catch或者try/catch捕获错误。错误码 401 表示参数错误比如传了个空的 PixelMap 进去。两种回调风格除了 Promise还可以用 callback 风格effectKit.createColorPicker(pixelMap,(error,colorPicker){if(error){console.error(Failed to create color picker.);}else{console.info(Succeeded in creating color picker.);}})两种写法效果一样看你喜欢哪种。指定取色区域API 10有时候你不想从整张图片取色只想取某个区域的。比如用户头像一般在图片的中心位置你只想从中心区域取色。这时候可以用带region参数的版本effectKit.createColorPicker(pixelMap,[0,0,1,1]).then(colorPicker{console.info(Succeeded in creating colorPicker.);})region是一个包含 4 个数字的数组分别表示左、上、右、下的位置取值范围[0, 1]。打个比方[0, 0, 1, 1]— 整张图片默认值[0.25, 0.25, 0.75, 0.75]— 图片中心区域从 25% 到 75%[0, 0, 0.5, 1]— 图片左半边[0, 0, 1, 0.5]— 图片上半边注意第三个值必须大于第一个右 左第四个必须大于第二个下 上不然会报 401 参数错误。getMainColor最常用的取色方式colorPicker.getMainColor().then(color{console.info(color[ARGB]${color.alpha},${color.red},${color.green},${color.blue});})getMainColor的原理是通过图像缩放算法根据周围像素的加权计算把整张图片缩小到 1 个像素。这 1 个像素的颜色就是主色。你可以把它想象成把一张照片缩小到 1x1 的缩略图那个缩略图的颜色就是主色。这其实也是很多提取主题色算法的基础思路。返回的Color对象有四个属性alpha透明度[0, 0xFF]red红色分量[0, 0xFF]green绿色分量[0, 0xFF]blue蓝色分量[0, 0xFF]如果你想要同步版本不返回 Promise可以用getMainColorSync()letcolorcolorPicker.getMainColorSync();console.info(get main color color);同步版本会在当前线程直接计算如果图片很大可能会卡一下。一般建议用异步版本。getLargestProportionColor占比最多的颜色letcolorcolorPicker.getLargestProportionColor();console.info(get largest proportion color color);这个方法使用中位切分算法Median Cut来划分颜色空间。简单说就是把图片里所有颜色按 RGB 值分成很多组每组里颜色数量差不多然后取数量最多的那组的平均颜色。和getMainColor的区别是什么getMainColor是加权平均可能得到一个不存在的颜色比如图片全是红色和蓝色主色可能是紫色。而getLargestProportionColor返回的是真实存在的颜色——图片里确实有大量像素是这个颜色。getTopProportionColors取前 N 种颜色letcolorscolorPicker.getTopProportionColors(2);for(letindex0;indexcolors.length;index){if(colors[index]){console.info(get top proportion colors: index index, color colors[index]);}}colorCount参数指定你要取几种颜色。返回一个 Color 数组按占比从高到低排序。这个方法很适合做主题色卡片——展示一张图片的 3-5 种主要颜色让用户选择用哪个做主题色。注意colorCount的取值范围是[1, 20]HarmonyOS 6.1.0 之前是[1, 10]。如果你传的值比实际颜色种类多返回的数组会比你要求的短——有多少返回多少。如果取色失败或者传了小于 1 的值返回[null]。getHighestSaturationColor最鲜艳的颜色letcolorcolorPicker.getHighestSaturationColor();console.info(get highest saturation color color);饱和度是什么你可以理解为颜色的鲜艳程度。纯红色饱和度很高灰色饱和度为 0。这个方法会找到图片里最鲜艳的那个颜色。适合什么场景比如你在做一个提取强调色的功能——APP 里需要一个醒目的颜色来高亮按钮或标签用饱和度最高的颜色就很合适。getAverageColor平均颜色letcolorcolorPicker.getAverageColor();console.info(get average color color);这个最直白——把所有像素的 RGBA 值各自加起来除以像素总数得到平均值。和getMainColor有什么区别getMainColor是缩放算法考虑了像素的位置权重getAverageColor是简单平均每个像素权重一样。结果可能很接近但不完全相同。isBlackOrWhiteOrGrayColor判断黑白灰letbJudgecolorPicker.isBlackOrWhiteOrGrayColor(0xFFFFFFFF);console.info(is black or white or gray color[bool](white) bJudge);这个方法接收一个颜色值number 类型范围[0, 0xFFFFFFFF]返回true或false告诉你这个颜色是不是黑白灰。什么时候用比如你在做一个自动适配深色模式的功能——如果图片的主色是黑色或深灰前景文字就用白色如果是白色或浅灰前景文字就用黑色。先用isBlackOrWhiteOrGrayColor判断一下再决定用什么颜色。完整示例从照片提取主题色面对不同的业务场景如何选择合适的取色方式可以参考下面的决策流程通用主色调需要真实存在的颜色展示多种主题色供选择需要醒目的强调色需要整体平均色调是否需要从图片提取颜色需要什么类型的颜色?getMainColorgetLargestProportionColorgetTopProportionColorsgetHighestSaturationColorgetAverageColor结果是否为黑白灰?使用该颜色好来一个完整的例子。我们读取一张图片提取它的主色然后用这个颜色作为页面背景import{image}fromkit.ImageKit;import{effectKit}fromkit.ArkGraphics2D;import{common}fromkit.AbilityKit;EntryComponentstruct Index{StatemainColor:string#FFFFFF;StatetopColors:string[][];asyncaboutToAppear():Promisevoid{constcontext:Contextthis.getUIContext().getHostContext()ascommon.UIAbilityContext;constfileData:Uint8Arrayawaitcontext.resourceManager.getRawFileContent(image.png);constbuffer:ArrayBufferfileData.buffer.slice(0);letimageSourceimage.createImageSource(buffer);letpixelMapawaitimageSource.createPixelMap();// 提取主色effectKit.createColorPicker(pixelMap).then(colorPicker{letcolorcolorPicker.getMainColorSync();this.mainColorrgba(${color.red},${color.green},${color.blue},${color.alpha/255});// 提取前 3 种主要颜色letcolorscolorPicker.getTopProportionColors(3);this.topColorscolors.filter((c):ciseffectKit.Colorc!null).map(crgb(${c.red},${c.green},${c.blue}));});}build(){Column(){Text(主题色展示).fontSize(24).fontColor(#FFFFFF).margin({bottom:20})// 展示主色Row(){Text(主色).fontSize(16)Rectangle().width(60).height(60).fill(this.mainColor)}.margin({bottom:20})// 展示前 N 种颜色Row(){ForEach(this.topColors,(color:string){Rectangle().width(40).height(40).fill(color).margin(5)})}}.width(100%).height(100%).backgroundColor(this.mainColor)}}这段代码做了什么从rawfile读取图片创建 PixelMap。用createColorPicker创建取色器。用getMainColorSync获取主色转换成 CSS 颜色字符串。用getTopProportionColors(3)获取前 3 种主要颜色。在页面上展示这些颜色并把主色设为背景色。几个实用技巧1. 先判断颜色类型再决定用法如果你提取出来的主色是黑白灰用isBlackOrWhiteOrGrayColor判断可能不太适合作为主题色——太素了。这时候可以改用getHighestSaturationColor取最鲜艳的颜色。2. 取色区域很重要一张风景照天空可能占了大半如果你从整张图取色主色可能是天空的蓝色。但你真正想要的可能是前景建筑的颜色。这时候用region参数缩小取色范围效果会好很多。3. 取色结果可以缓存getMainColor这类方法每次调用都会重新计算。如果图片没变结果也不会变所以可以把结果缓存起来避免重复计算。4. 注意线程安全ColorPicker 的方法都在当前线程执行如果图片很大计算可能比较耗时。建议在子线程或者用 Promise 异步处理不要在 UI 线程同步调用。小结ColorPicker提供了多种取色方式适合不同的场景方法适用场景getMainColor通用取色适合大多数情况getLargestProportionColor需要真实存在的颜色getTopProportionColors展示多种主题色供用户选择getHighestSaturationColor提取最鲜艳的强调色getAverageColor需要整体色调的平均值isBlackOrWhiteOrGrayColor判断颜色类型辅助决策配合region参数指定取色区域基本能满足各种从图片提取颜色的需求。下一篇我们进入 ArkGraphics 2D 的 drawing 模块看看怎么用 Canvas、Brush、Pen 来画图——这才是真正的 2D 绘制能力。
http://www.gsyq.cn/news/1407234.html

相关文章:

  • 控糖别瞎吃粗粮!中医公认它是粗粮之王,升糖慢、还养脾胃
  • 2026年闵行那些靠谱的回收黄金加工厂家揭秘 - 资讯纵览
  • 2026年饶阳钢格栅采购选型与合规落地全攻略 - 资讯纵览
  • 火爆分享使用Taotoken后API调用延迟与稳定性的真实体感
  • MCP测试v4
  • 每月12美元自建AI助手:开源模型+云服务器实战部署指南
  • 深圳电子元器件供应商哪家种类全
  • Qwen-Edit-2509多角度图像生成:用自然语言指令重塑视觉创作
  • 2026重庆全屋定制公司推荐排行榜 五大高端品牌实力深度测评 - 资讯快报
  • 终极指南:如何使用SMPL-X将动作捕捉数据转换为逼真3D人体模型
  • 零信任架构:打破边界,构筑以身份为核心的新一代安全体系
  • 通过Taotoken模型广场快速了解并接入最新旗舰模型
  • 生产数据库批量 UPDATE / DELETE 核心要点-不备份=自行提桶跑路
  • 【Radan 2026.1 正式发布】更智能、更高效,钣金加工再升级!
  • 《PCI Express体系结构导读13》-- 中断(MSI/MSI-X)已付费
  • 紧急预警:AI歌词版权雷区已升级!ChatGPT辅助创作合规指南(含中国音著协2024最新备案流程)
  • 最新!2026生物除臭箱厂家精选推荐:综合实力与实用性能参考 - 资讯快报
  • 如何彻底解决网盘下载慢问题:LinkSwift八大网盘直链下载神器完全指南
  • 观察在ubuntu环境下通过taotoken调用大模型的延迟与稳定性表现
  • 云端AI模型选型实战:从397B巨无霸到1.6秒黑马,性能与成本的深度权衡
  • 2026上海二奢回收避坑指南|6大维度实测,这几家零投诉门店公开 - GrowthUME
  • MCP博客园工具集成测试v3
  • 小米 MiMo-V2.5 最高降价 99%:Token 战争背后,是一套押注 Agent 的工程算盘
  • 2026年5月惠州设计装修行业研究报告:高性价比排行榜揭晓 - 资讯纵览
  • 2026年iPaaS系统集成平台怎么选?国内主流产品深度对比与选型指南
  • FPGA实现ANU轻量级密码:4位到32位数据路径架构的权衡与实践
  • FPGA实现ANU轻量级密码:4位到32位数据路径架构的权衡与实践
  • 2026年宿迁木门厂家推荐榜:宿迁木门定做、宿迁铝门定做厂家选择指南,成艺门业的场景化工艺切入 - 海棠依旧大
  • 2026替换液压油缸的优选方案:耐高温工业推杆推荐 - 资讯快报
  • HLS Downloader:重新定义浏览器流媒体下载的边界与体验