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

HarmonyOS 离屏截图实战:createFromBuilder 动态生成图片的完整流程

文章目录

    • 背景
      • 方法总览
      • 什么是离屏渲染?
      • 第一步:定义顶层 @Builder 函数
      • 第二步:调用 createFromBuilder
      • checkImageStatus 参数的作用
      • 截图结果显示
      • delay 怎么设合适?
      • 完整代码示例
      • createFromBuilder vs get(),怎么选?
      • 写在最后

背景

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

案例demo导航展示

↓↓↓↓↓↓接下来言归正传 ↓↓↓↓
上一篇讲了用get()截取已经显示在屏幕上的组件。但有时候你需要生成一张图片,这张图片对应的 UI 组件并不需要显示给用户看,只是用来生成图片内容——比如分享卡片、动态生成海报。

这种场景就需要用到createFromBuilder:离屏渲染。

方法总览

什么是离屏渲染?

正常的 UI 渲染是把组件画到屏幕上,用户能看到。离屏渲染是把组件"画"在一块内存缓冲区里,用户看不到,但我们可以把这块缓冲区的内容转成图片。

整个流程是:

  1. 定义一个@Builder函数描述 UI 内容
  2. 调用createFromBuilder,把这个 Builder 传进去
  3. 系统在内存里渲染这个 UI
  4. 截取内存里的内容,返回PixelMap
  5. 你拿到PixelMap可以显示、保存、上传

第一步:定义顶层 @Builder 函数

关键点createFromBuilder接受的是顶层@Builder函数(不是 struct 里的@Builder方法),必须定义在 struct 外面。

// 必须定义在组件 struct 外部@BuilderfunctionbuilderParam(){Column({space:6}){Text('SnapshotUtil 离屏渲染示例').fontSize(16).fontColor('#FFFFFF').fontWeight(FontWeight.Bold)Text('createFromBuilder 截图内容').fontSize(12).fontColor('#CCFFCC')Row({space:6}){Circle({width:20,height:20}).fill('#FF6B6B')Circle({width:20,height:20}).fill('#4ECDC4')Circle({width:20,height:20}).fill('#FFE66D')}}.width(260).height(100).backgroundColor('#2C3E50').borderRadius(12).justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center)}

这个 Builder 定义了一张深色背景、有文字和彩色圆圈的小卡片。它不会显示在屏幕上,只用于离屏渲染。

第二步:调用 createFromBuilder

createFromBuilder接受三个参数:

  • 第一个:@Builder函数引用
  • 第二个:delay(延迟毫秒数),让组件有时间完成渲染
  • 第三个:checkImageStatus(是否检查图片加载状态)
this.Btn('createFromBuilder(builderParam, delay=300)','#9B59B6',()=>{SnapshotUtil.createFromBuilder(builderParam,300,false).then(pm=>{this.builderPixelMap=pm;this.addLog(`createFromBuilder() → PixelMap${pm.getPixelBytesNumber()}bytes`);}).catch((e:Error)=>{this.addLog(`createFromBuilder() Error:${e.message}`);});})

delay=300的意思是等待 300 毫秒再截图,给系统时间完成布局和渲染。

checkImageStatus 参数的作用

如果 Builder 里包含Image组件(比如从网络加载的图片),图片加载是异步的,截图时图片可能还没加载完。这时候把checkImageStatus设为true,系统会等图片加载完毕再截图:

this.Btn('createFromBuilder(builderParam, delay=500, checkImageStatus=true)','#8E44AD',()=>{SnapshotUtil.createFromBuilder(builderParam,500,true).then(pm=>{this.builderPixelMap=pm;this.addLog(`createFromBuilder(delay=500) →${pm.getPixelBytesNumber()}bytes`);}).catch((e:Error)=>{this.addLog(`createFromBuilder Error:${e.message}`);});})

delay=500, checkImageStatus=true:等 500ms 并检查图片状态,适合 Builder 里有网络图片的情况。

截图结果显示

拿到PixelMap后,用Image组件显示:

if(this.builderPixelMap!==undefined){this.SectionTitle('离屏截图预览')Image(this.builderPixelMap).width('100%').height(120).objectFit(ImageFit.Contain).backgroundColor('#F0F0F0').borderRadius(8)}

delay 怎么设合适?

这个值没有固定标准,要根据 Builder 里的内容复杂程度来决定:

Builder 内容建议 delay
只有文字和基本图形200~300ms
有本地图片资源300~500ms
有网络图片(配合 checkImageStatus=true)500~1000ms
复杂布局+多张图片800ms+

设太小可能截到空白内容,设太大用户等待时间长。建议先用 300ms 试,如果有空白内容就加长。

完整代码示例

import{SnapshotUtil}from'../Utils/SnapshotUtil';import{image}from'@kit.ImageKit';@Entry@Componentstruct CreateFromBuilderDemo{@StatebuilderPixelMap:image.PixelMap|undefined=undefined;build(){Column({space:12}){Button('生成离屏截图').onClick(()=>{SnapshotUtil.createFromBuilder(builderParam,300,false).then(pm=>{this.builderPixelMap=pm;}).catch((e:Error)=>{console.error('离屏截图失败:',e.message);});})if(this.builderPixelMap!==undefined){Text('离屏截图结果:').fontSize(13).fontColor('#888')Image(this.builderPixelMap).width('100%').height(120).objectFit(ImageFit.Contain).backgroundColor('#F0F0F0').borderRadius(8)}}.padding(16)}}// Builder 必须定义在 struct 外部@BuilderfunctionbuilderParam(){Column({space:6}){Text('SnapshotUtil 离屏渲染示例').fontSize(16).fontColor('#FFFFFF').fontWeight(FontWeight.Bold)Text('createFromBuilder 截图内容').fontSize(12).fontColor('#CCFFCC')Row({space:6}){Circle({width:20,height:20}).fill('#FF6B6B')Circle({width:20,height:20}).fill('#4ECDC4')Circle({width:20,height:20}).fill('#FFE66D')}}.width(260).height(100).backgroundColor('#2C3E50').borderRadius(12).justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center)}

createFromBuilder vs get(),怎么选?

场景推荐方法
截取屏幕上已有的组件get(id)
动态生成不需要显示的图片createFromBuilder
生成分享海报、卡片图createFromBuilder
截取当前页面某个区域get(id)

写在最后

createFromBuilder是生成动态图片的利器,特别适合"分享给朋友"这种功能——生成一张带用户数据的卡片图,直接分享,不需要专门做一个页面让用户看。

掌握这个方法,很多"截图生成"需求都能轻松搞定。

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

相关文章:

  • AI生成内容不可篡改存证方案:基于零知识证明的区块链艺术溯源系统(已通过国家网信办备案编号:AIGC-2024-087)
  • Carbon-3B性能优化:10个提升DNA序列生成速度的技巧
  • 实战指南:5步打造高效数据可视化大屏
  • BG3模组管理器终极教程:从安装到精通完整指南
  • HarmonyOS SnapshotUtil 组件截图完全指南:get() 异步截图 vs getSync() 同步截图
  • 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机器人助手