当前位置: 首页 > 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.rkmt.cn/news/1430150.html

相关文章:

  • Granite-Embedding-97M-Multilingual-R2:IBM革命性多语言嵌入模型,如何在200+语言中实现高效检索?
  • AI生成内容不可篡改存证方案:基于零知识证明的区块链艺术溯源系统(已通过国家网信办备案编号:AIGC-2024-087)
  • BG3模组管理器终极教程:从安装到精通完整指南
  • CANN/asc-devkit矩阵计算实践
  • AI服务合规生死线:Gemini条款生成必须绕过的7个致命漏洞(2024最新监管判例实录)
  • HarmonyOS SnapshotUtil 窗口截图与系统截屏监听:snapshot() 和 onSnapshotListener 详解
  • 创业者必看:柳州螺蛳粉技术培训哪家靠谱?实力全测评 - 资讯纵览
  • 告别密密麻麻!ECharts饼图图例太多怎么优雅分页?scroll配置全解析
  • ControlNet-XS with Stable Diffusion XL完全指南:从安装到生成高质量图像的简单教程
  • 三协议合一:如何用LuckyLilliaBot打造你的全能QQ机器人助手
  • xss-filters实战教程:保护HTML数据与属性的10个最佳实践
  • 鸣潮自动化工具终极指南:如何实现后台智能战斗与资源收集
  • 基于ESP8266与PI算法的公交车智能限速系统设计与实现
  • 日喀则本地专业防水TOP5靠谱推荐:家里漏水不用愁,免费上门不求人。本地最新防水企业资讯:专业师傅持证上门,收费透明无隐藏收费,质保5-10年,售后有保障 - 企业资讯
  • 如何零成本将3D视频变2D?VR-Reversal让你告别VR设备也能享受沉浸体验
  • 房地产AI合规红线清单(含住建部新规+GDPR+生成式AI备案要求),错过即停用
  • 西安本地专业防水TOP5靠谱推荐:家里漏水不用愁,免费上门不求人。本地最新防水企业资讯:专业师傅持证上门,收费透明无隐藏收费,质保5-10年,售后有保障 - 企业资讯
  • CatPPT部署实战:从本地环境到云端服务的完整配置指南
  • 为什么选择StableDiffusionXL_instruct_pix2pix?对比其他AI图像编辑工具的10大优势
  • 【Gemini安全审计报告深度解密】:20年攻防专家亲授3大高危漏洞识别法与72小时应急响应清单
  • 终极指南:如何用HS2-HF_Patch一键解决Honey Select 2所有烦恼
  • GPT2_PMC部署实战:从模型加载到API服务的完整教程
  • 中国(甘肃)-哈萨克斯坦特色产业合作对接会在兰举行
  • 医院商用净水服务商哪家专业:深度专业实力解析 - 19120507004
  • 【车辆SLAM】Rao-Blackwellized粒子滤波器两辆自动驾驶车辆的协作SLAM(距离承载、仅方位、数据关联 全EKF SLAM配合传感器融合策略)【含Matlab源码 1
  • 如何快速上手bert-large-portuguese-cased:5分钟葡萄牙语NLP入门教程
  • 曲靖本地专业防水TOP5靠谱推荐:家里漏水不用愁,免费上门不求人。本地最新防水企业资讯:专业师傅持证上门,收费透明无隐藏收费,质保5-10年,售后有保障 - 企业资讯
  • Aya-101安全与偏见评估:多语言环境下的AI伦理挑战
  • 荆州本地专业防水TOP5靠谱推荐:家里漏水不用愁,免费上门不求人。本地最新防水企业资讯:专业师傅持证上门,收费透明无隐藏收费,质保5-10年,售后有保障 - 企业资讯
  • 终极指南:如何在Ollama中部署Qwen3-235B-A22B-Thinking-2507-FP8推理模型