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

HarmonyOS 图片缩放没想象中简单——detailEnhance 四档质量深度解析

文章目录先搞清楚为什么不直接用系统缩放整体数据流核心代码拆解第一步创建源 PixelMap 和目标 PixelMap第二步用 Select 控件选择档位并触发增强第三步Native 层接口声明Index.d.ts四档质量对比踩坑总结StorageLink 实现跨页面状态共享写在最后用 ImageKit 处理图片缩放第一次用的时候我以为就是个 resize结果发现里面有个detailEnhance的参数四个挡位差异挺大的。这篇文章就把这块说透。先搞清楚为什么不直接用系统缩放普通的scale()或者直接改 PixelMap 尺寸底层用的是最近邻或双线性插值放大之后会明显模糊、出锯齿。detailEnhance是走了 C Native 层的图像增强算法相当于给缩放结果做了一轮超分辨率处理。用大白话说NONE直接缩放最快质量最差LOW轻度增强比 NONE 稍好一点速度也快MEDIUM中等增强日常使用最均衡的选择HIGH最强增强细节最好耗时最长不适合实时处理整体数据流核心代码拆解第一步创建源 PixelMap 和目标 PixelMapimport{image}fromkit.ImageKit;importnativePixfromlibentry.so;import{hilog}fromkit.PerformanceAnalysisKit;getPixMap():void{try{// 从 rawfile 创建 ImageSourceletimageSource:image.ImageSourceimage.createImageSource(this.getUIContext().getHostContext()?.resourceManager.getRawFdSync(ic_scaling.png));// 同步解码为 PixelMapthis.pixelMapSrcimageSource.createPixelMapSync();// 获取原始尺寸constimageInfo:image.ImageInfothis.pixelMapSrc.getImageInfoSync();this.inputWidthimageInfo.size.width;this.inputHeightimageInfo.size.height;// 创建目标 PixelMap放大 1.5 倍constopts:image.InitializationOptions{editable:true,pixelFormat:image.PixelMapFormat.RGBA_8888,size:{height:imageInfo.size.height*this.zoomRatio,// zoomRatio 1.5width:imageInfo.size.width*this.zoomRatio}};this.pixelMapDstimage.createPixelMapSync(opts);}catch(e){hilog.error(0x0000,ImageScaling,getPixMap error${JSON.stringify(e)});}}注意目标 PixelMap 是个空白画布真正的像素写入是由 Native 层的detailEnhance完成的。不要以为createPixelMapSync(opts)就直接缩放好了。第二步用 Select 控件选择档位并触发增强Componentexportstruct ImageScalingComponent{Stateindex:number0;// 对应 NONE0, LOW1, MEDIUM2, HIGH3StatepixelMapSrc:image.PixelMap|undefinedundefined;StatepixelMapDst:image.PixelMap|undefinedundefined;StateinputWidth:number0;StateinputHeight:number0;privatezoomRatio:number1.5;build(){Column(){// 展示原图Image($rawfile(ic_scaling.png)).width(100%).aspectRatio(1.25)// 选择增强档位Select([{value:NONE},{value:LOW},{value:MEDIUM},{value:HIGH}]).selected(this.index).onSelect((index:number,text:string){this.indexindex;// 每次选择都重新创建目标 PixelMapthis.pixelMapDstundefined;this.getPixMap();// 调用 Native 增强接口// 第五个参数 index: 0NONE, 1LOW, 2MEDIUM, 3HIGHnativePix.detailEnhance(this.pixelMapSrc,this.pixelMapDst,this.inputWidth,this.inputHeight,this.index);this.isShowtrue;})// 展示增强后的结果if(this.isShow){Image(this.pixelMapDst).width(100%).aspectRatio(1.25)}}}}第三步Native 层接口声明Index.d.ts// libentry.so 对应的 TypeScript 类型声明exportconstdetailEnhance:(src:image.PixelMap|undefined,dst:image.PixelMap|undefined,width:number,height:number,quality:number// 0:NONE 1:LOW 2:MEDIUM 3:HIGH)void;exportconstcreatePixelMap:(height:number,width:number)image.PixelMap;四档质量对比档位对应 index处理速度细节保留适用场景NONE0最快最差放大后模糊明显缩略图预览LOW1快略好于 NONE列表图片MEDIUM2中等均衡细节较好日常图片展示HIGH3慢最佳细节锐利打印、精细展示踩坑总结坑1目标 PixelMap 必须每次重新创建每次切换档位时pixelMapDst undefined然后重新getPixMap()是必要的。如果复用旧的 PixelMap上次的像素数据会残留Native 层写入可能出现异常。坑2pixelFormat 必须是 RGBA_8888创建目标 PixelMap 时pixelFormat要指定RGBA_8888不能省略。如果用UNKNOWN或者其他格式Native 层写入会失败并返回错误码。坑3宽高顺序注意detailEnhance接口的参数是(src, dst, inputWidth, inputHeight, quality)但createPixelMap的参数顺序是(height, width)。这两个顺序不一样写错了图会出现拉伸变形。坑4SELECT 选同一项不触发 onSelectSelect 组件如果选的是当前已选项onSelect不会触发。如果需要强制刷新要额外加一个按钮来重新处理。StorageLink 实现跨页面状态共享项目里用了一个很精妙的设计色彩空间转换页生成 HDR 图后元数据生成页和 HDR 层转换页才会激活。这是用StorageLinkAppStorage做的。// 主页Index.etsStorageLink(hdrPixelMap)hdrPixelMap:image.PixelMap|undefinedundefined;// 按钮动态启用/禁用HDR 图存在才能点Button(元数据生成).enabled(this.hdrPixelMap!undefined)// 色彩空间转换页生成 HDR 图后if(imageInfo.isHdr){this.hdrPixelMapthis.pixelMapSrc;// AppStorage 自动同步}不需要回调不需要事件总线状态一改所有绑定了StorageLink(hdrPixelMap)的组件都会自动更新。写在最后图片缩放不是把尺寸改了就完事算法档位的选择对用户体验影响很大。MEDIUM 是大多数场景的最优解HIGH 留给需要打印或精细展示的场景。另外要记住Native 层接口是同步调用HIGH 档处理大图时会卡住 UI 线程生产环境记得放到 TaskPool 里跑。
http://www.zskr.cn/news/1335368.html

相关文章:

  • 告别理论推导!用Python+NumPy手撸一个卡尔曼滤波器(附AR序列预测完整代码)
  • 2026四川全屋定制打印机实力厂家排行及地址汇总:高温彩釉打印机/700度高温烧结打印机/uv光油墨水/排行一览 - 优质品牌商家
  • SAP-ABAP:数据类型与数据对象(8篇) 第八篇:误区避坑篇——数据类型与对象操作的常见误区解析
  • 别再一个个置位了!博图PLC编程效率翻倍:SET_BF指令结合ARRAY的进阶玩法
  • FreeRTOS信号量实战:从同步互斥原理到嵌入式并发编程避坑指南
  • 【必记】2026年 {论文题} |范文记忆提纲 → 整合管理 质量管理
  • 揭秘嘉兴桐乡零投诉全屋定制,源头工厂实力派
  • eclipse数值模拟器并行计算
  • 除了ModHeader,还有哪些HTTP头修改插件?离线安装全攻略与横向评测
  • 3岁孩子能不能喝花姐八珍粉?怎么控制用量?
  • 从‘Hello World’到自主导航:一个ROS1节点的完整生命周期与调试指令全记录
  • 别再只用按键了!用STM32F103的ADC读取电位器,给你的无感无刷电机做个“油门”
  • 【PostgreSQL】时间取最大值,转换为init,如果为空则为0
  • 告别Vivado HLS!Vitis HLS 2021.1保姆级教程:从C++代码到FPGA IP核的完整流程
  • 手把手教你用STM32F103C8T6驱动DS18B20,附完整代码和LCD1602显示教程
  • 2026年5月热门的上海代办德国子公司注册口碑推荐厂家推荐榜,全流程代办、法务税务合规、签证支持型厂家选择指南 - 海棠依旧大
  • 美股api的WebSocket偶尔断连,心跳间隔设多少秒最合适?
  • 2026-05-21:变成目标数组的最少操作次数。用go语言,给定两个长度相同的数组 nums 和 target。 - nums[i] 表示当前位置 i 当前的值。 - target[i] 表示当前位
  • 告别理论!用Python可视化带你彻底搞懂电机插补算法(逐点比较法)
  • 深入ARM Cortex-M内核:除了性能参数,这些设计细节才是嵌入式稳定的关键
  • 2026年5月广西工程咨询公司哪家强?商业计划书编制机构推荐榜,可行性研究报告、项目建议书、资金申请报告厂家选择指南 - 海棠依旧大
  • Xilinx Zynq MPSoC开发实战:从Vivado到SDK的Hello World全流程解析
  • 告别串口助手!用手机APP和ESP-01S模块,5分钟搞定51单片机无线控制LED
  • 在i.MX6UL嵌入式Linux上部署ncnn:轻量级AI推理实践与优化
  • 数字化转型最大的谎言:上了低代码就能“降本增效”?
  • 鸿蒙支付模块构建:快捷充值选项与缴费记录的时间线设计
  • 2026年一人公司创业指南:OPC模式如何稳健起步
  • Alist启动报错?别慌!手把手教你用Windows命令排查并解决5244端口占用问题
  • 起酥油:市场发展现状与未来前景趋势
  • 不同场景怎么处理文档?PDF 翻译、Office 翻译、AI 美化和多语言交付指南