大家可以试想一下这样的功能场景:
-
用户在完成了一系列的学习积分和考试后,能够获得一张证书,这个证书除了通用的底图外,对于姓名,时间,成绩等数据是根据用户情况动态生成的,然后还需要有将证书保存到相册的情况
-
在一些记账类app中,用户可以通过图表的形似查看自己的消费趋势,并期望将这个图表以图片的形式保存下来
-
在一些AI生成类项目中,对于AI生成的内容,通过图片形式保存到相册里以方便分享,或者直接导出图片格式后进行分享操作
对于以上这些功能,都需要用到"组件截图"这个功能模块,当然,现在鸿蒙已经提供了@ohos.arkui.componentSnapshot (组件截图)这个现成的模块,但是,除了基本的导出PixelMap格式的图片信息以外,其他的操作,例如保存到相册等功能还是要做一些其他操作的,为了简化整个流程,推荐一个第三方的库:screenshot_hm
功能特性
- ✅ 组件截图: 支持对任意设置了ID的组件进行截图
- ✅ 动态内容支持: 完美支持@State状态变化、ForEach列表渲染等动态内容的截图
- ✅ 原生SaveButton: 使用官方SaveButton组件,自动处理权限和用户交互
- ✅ 临时文件机制: 截图生成临时文件,通过SaveButton保存到相册
- ✅ 本地文件保存: 同时支持保存到应用本地文件系统
- ✅ 截图预览: 支持在应用内预览截图效果
- ✅ 高质量输出: 支持PNG格式,100%质量输出
- ✅ 资源管理: 自动释放内存资源,避免内存泄漏
基础安装
typescript
ohpm install screenshot_hm
1. 导入库文件
typescript
import { ScreenshotUtils } from 'screenshot_hm';
核心实现
1. 截图工具类
ScreenshotUtils.ets
提供了完整的截图功能:
typescript
// 截图并保存到临时文件,返回文件路径供SaveButton使用
const tempPath = await ScreenshotUtils.captureAndSaveToTemp(
'componentId', // 组件ID
context, // 应用上下文
'filename.png' // 可选的文件名
);
// 获取截图PixelMap
const pixelMap = await ScreenshotUtils.captureComponentToPixelMap('componentId');
// 将PixelMap保存到临时文件
const tempPath = await ScreenshotUtils.savePixelMapToTemp(pixelMap, context);
// 预览截图
await ScreenshotUtils.previewCapture('componentId', (pixelMap) => {
// 处理截图预览
});
2. SaveButton使用方式
按照华为官方文档标准实现:
typescript
SaveButton() // 创建安全控件按钮。
.onClick(async (event, result: SaveButtonOnClickResult) => {
if (result == SaveButtonOnClickResult.SUCCESS) {
try {
let context = getContext();
let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
let path = await ScreenshotUtils.captureAndSaveToTemp(
"jietu", //组件的id
this.context, // private context = getContext(this) as common.UIAbilityContext;
`component_${Date.now()}.png` //文件名
);
let assetChangeRequest: photoAccessHelper.MediaAssetChangeRequest = photoAccessHelper.MediaAssetChangeRequest.createImageAssetRequest(context, path);
await phAccessHelper.applyChanges(assetChangeRequest);
console.info('createAsset successfully, uri: ' + assetChangeRequest.getAsset().uri);
} catch (err) {
console.error(`create asset failed with error: ${err.code}, ${err.message}`);
}
} else {
console.error('SaveButtonOnClickResult create asset failed');
}
})
可以看到整体使用方式非常简单,和使用componentSnapshot一样,只需要对组件指定一个id就可以进行截图,但相比之下,在保存到相册、形成临时文件方面,比直接使用componentSnapshot简单了太多