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

HarmonyOS SnapshotUtil 组件截图完全指南:get() 异步截图 vs getSync() 同步截图

文章目录

    • 背景
      • 方法总览
      • 先准备:给目标组件设置 id
      • get():异步截图(推荐)
      • getSync():同步截图
      • get() 和 getSync() 怎么选?
      • 截图预览完整示例
      • 常见问题
      • 写在最后

背景

近期发现一款很有意思的HarmonyOS 三方库, 地址 @pura/harmony-utils(V1.4.0) , 作者是"桃花镇童长老", 我这里也是直接通过该作者公布的源码进行案例编写进行,写了到目前写了一部分demo ,感觉确实很有帮助,这里呢也是开始写一个系列的演示demo 供大家参考。如有帮助可以在OpenHarmony中进行下载安装进行使用哦

案例demo导航展示

↓↓↓↓↓↓接下来言归正传 ↓↓↓↓
做 HarmonyOS 应用经常会遇到这种需求:截取某个特定组件的图片,比如分享一张卡片、保存用户信息预览图。系统提供了组件截图能力,但 API 用起来有点绕。HoUtils 的SnapshotUtil把这些封装好了,这篇就来讲怎么用。

方法总览

先准备:给目标组件设置 id

组件截图的关键是给目标组件打上 id 标记,截图时通过这个 id 找到对应的组件。

// 被截图的目标组件,必须设置 idColumn({space:8}){Text('这是一个演示组件').fontSize(16).fontColor('#333').fontWeight(FontWeight.Bold)Text('可对该区域进行组件截图').fontSize(13).fontColor('#666')Row({space:8}){ForEach(['红','绿','蓝'],(label:string,idx:number)=>{Column(){Circle({width:40,height:40}).fill(idx===0?'#FF6B6B':idx===1?'#4ECDC4':'#45B7D1')Text(label).fontSize(12).fontColor('#666')}},(label:string)=>label)}}.id('snapshot_target')// 关键:设置组件 id.width('100%').padding(16).backgroundColor('#FFFFFF').borderRadius(10).border({width:2,color:'#4A90E2',style:BorderStyle.Dashed})

注意.id('snapshot_target')这一行,这是截图能找到组件的前提。

get():异步截图(推荐)

get()是异步方式,不会阻塞 UI 线程,是推荐的使用方式。

基本用法

SnapshotUtil.get('snapshot_target').then(pm=>{this.snapshotPixelMap=pm;this.addLog(`get("snapshot_target") → PixelMap${pm.getPixelBytesNumber()}bytes`);}).catch((e:Error)=>{this.addLog(`get() Error:${e.message}`);});

返回的是PixelMap对象,可以直接赋给Image组件显示:

if(this.snapshotPixelMap!==undefined){Image(this.snapshotPixelMap).width('100%').height(120).objectFit(ImageFit.Contain).backgroundColor('#F0F0F0').borderRadius(8)}

带 options 的用法(缩放截图)

SnapshotUtil.get('snapshot_target',{scale:0.5}).then(pm=>{this.snapshotPixelMap=pm;this.addLog(`get("snapshot_target", {scale:0.5}) →${pm.getPixelBytesNumber()}bytes`);}).catch((e:Error)=>{this.addLog(`get() Error:${e.message}`);});

scale: 0.5表示缩放为原始大小的 50%,截出来的图片尺寸更小,文件也更小。

getSync():同步截图

getSync()是同步版本,直接返回PixelMap,用try/catch处理异常:

this.Btn('getSync("snapshot_target")','#16A085',()=>{try{constpm=SnapshotUtil.getSync('snapshot_target');this.snapshotPixelMap=pm;this.addLog(`getSync("snapshot_target") → PixelMap${pm.getPixelBytesNumber()}bytes`);}catch(e){this.addLog(`getSync() Error:${e}`);}})

还可以传waitUntilRenderFinished: true,等待渲染完成再截图:

this.Btn('getSync() 带 options (waitUntilRenderFinished=true)','#148F77',()=>{try{constpm=SnapshotUtil.getSync('snapshot_target',{waitUntilRenderFinished:true});this.snapshotPixelMap=pm;this.addLog(`getSync({waitUntilRenderFinished:true}) →${pm.getPixelBytesNumber()}bytes`);}catch(e){this.addLog(`getSync() Error:${e}`);}})

waitUntilRenderFinished: true适合那种组件里有动画、异步加载图片等情况,确保内容完全渲染完再截图,避免截到空白。

get() 和 getSync() 怎么选?

get()(异步)getSync()(同步)
是否阻塞 UI是(可能短暂卡顿)
错误处理.catch()try/catch
适合场景常规截图,用户点击触发需要立即拿到结果,截图后立刻处理
推荐程度✅ 首选按需使用

截图预览完整示例

import{SnapshotUtil}from'../Utils/SnapshotUtil';import{image}from'@kit.ImageKit';@Entry@Componentstruct SnapshotUtilDemoPage{@StatesnapshotPixelMap:image.PixelMap|undefined=undefined;build(){Column(){// 目标组件Column({space:8}){Text('这是一个演示组件').fontSize(16).fontColor('#333').fontWeight(FontWeight.Bold)Text('可对该区域进行组件截图').fontSize(13).fontColor('#666')Row({space:8}){ForEach(['红','绿','蓝'],(label:string,idx:number)=>{Column(){Circle({width:40,height:40}).fill(idx===0?'#FF6B6B':idx===1?'#4ECDC4':'#45B7D1')Text(label).fontSize(12).fontColor('#666')}},(label:string)=>label)}}.id('snapshot_target').width('100%').padding(16).backgroundColor('#FFFFFF').borderRadius(10)// 截图按钮Button('截取组件').onClick(()=>{SnapshotUtil.get('snapshot_target').then(pm=>{this.snapshotPixelMap=pm;}).catch((e:Error)=>{console.error('截图失败:',e.message);});})// 截图预览if(this.snapshotPixelMap!==undefined){Text('截图预览:').fontSize(13).fontColor('#888')Image(this.snapshotPixelMap).width('100%').height(120).objectFit(ImageFit.Contain).backgroundColor('#F0F0F0').borderRadius(8)}}}}

常见问题

Q:截图结果是黑屏或空白?

可能原因:

  1. 组件还没渲染完成,试试getSync配合waitUntilRenderFinished: true
  2. 组件 id 写错了,检查.id()的值和get()传的参数是否一致

Q:截图后怎么保存到相册?

拿到PixelMap之后,可以结合ImageUtil@ohos.multimedia.image的 packer 打包成 JPEG/PNG 文件,再用photoAccessHelper保存到相册。

写在最后

get()配合PixelMap再渲染成Image组件,基本上覆盖了 90% 的组件截图需求。下一篇聊createFromBuilder——不需要组件在屏幕上,直接离屏渲染并截图。

http://www.jsqmd.com/news/918821/

相关文章:

  • SECS/GEM协议Python实现终极指南:快速构建半导体设备通信系统
  • 2026达州瑜伽普拉提培训机构深度评测报告 - 资讯纵览
  • Stoic模型与其他蛋白质预测工具对比:优势和适用场景分析
  • xss-filters:终极XSS防护解决方案,让Web应用安全无忧
  • AIFS ENS v2.0训练秘籍:32个GH200 GPU如何打造气象AI模型?
  • AI服务合规生死线:Gemini条款生成必须绕过的7个致命漏洞(2024最新监管判例实录)
  • MacBook上从零搞定LangChain:Python环境配置到第一个向量数据库应用(避坑指南)
  • CANN/asc-devkit矩阵计算实践
  • 12种语言支持:Granite-3.0-2B-Base-GGUF多语言文本生成实战指南
  • AI时代最值钱的能力,不是会写Prompt,而是会验证真相
  • CANN/asc-devkit SIMD向量函数Dump接口
  • HarmonyOS SnapshotUtil 窗口截图与系统截屏监听:snapshot() 和 onSnapshotListener 详解
  • 创业者必看:柳州螺蛳粉技术培训哪家靠谱?实力全测评 - 资讯纵览
  • 树莓派Pico与BMP180传感器:从I2C通信到微型气象站搭建实践
  • 5分钟实战:draw.io桌面版深度构建指南,从源码到跨平台安装包
  • SmolLM2-1.7B-Instruct部署优化:NPU与CPU环境下的性能调优技巧
  • 灵达科技亮相天津智博会,存储互联+高速互联双赛道
  • 告别密密麻麻!ECharts饼图图例太多怎么优雅分页?scroll配置全解析
  • 提升用户体验:gh_mirrors/li/live2d_demo事件触发与交互设计指南
  • 2026南充瑜伽普拉提培训机构深度评测报告 - 资讯纵览
  • 三步轻松备份微信聊天记录:你的数字记忆保险箱 [特殊字符]️
  • ControlNet-XS with Stable Diffusion XL完全指南:从安装到生成高质量图像的简单教程
  • xss-filters实战教程:保护HTML数据与属性的10个最佳实践
  • 186、运动控制中的行业应用:无人机飞控
  • 三协议合一:如何用LuckyLilliaBot打造你的全能QQ机器人助手
  • ACE-Step 1.5 XL Turbo商业授权指南:合法合规使用AI生成音乐的终极攻略
  • 鸣潮自动化工具终极指南:如何实现后台智能战斗与资源收集
  • 基于ESP8266与PI算法的公交车智能限速系统设计与实现
  • DLSS Swapper技术架构深度解析:跨平台游戏DLSS文件管理系统的实现原理
  • 别再让远处的模型糊成一片了!在Unity/UE4里正确开启Mipmap的保姆级教程