
回复
项目源码已发布到GitCode平台, 方便开发者进行下载和使用。
harmonyOSAvatar
主页面效果如下:
侧边栏效果如下
在HarmonyOS应用开发中,有时需要将界面上的组件保存为图片,例如制作头像、分享截图等场景。本教程将详细介绍如何使用HarmonyOS提供的API实现组件快照获取和图片保存功能,包括组件快照捕获、图像处理和文件系统操作。
本教程涵盖以下关键技术点:
componentSnapshot
获取组件快照image
模块处理图像数据fs
文件系统模块保存图像photoAccessHelper
将图像保存到系统相册import componentSnapshot from '@ohos.arkui.componentSnapshot'
import image from '@ohos.multimedia.image'
import fs from '@ohos.file.fs';
import photoAccessHelper from "@ohos.file.photoAccessHelper";
import { promptAction } from "@kit.ArkUI";
为了确保每次保存的图片文件名唯一,我们可以使用时间戳作为文件名的一部分:
/**
* 获取当前时间的拼接字符串,用于图片命名
*/
function getTimeStr(): string {
const now: Date = new Date();
const year: number = now.getFullYear();
const month: number = now.getMonth() + 1;
const day: number = now.getDate();
const hours: number = now.getHours();
const minutes: number = now.getMinutes();
const seconds: number = now.getSeconds();
return `${year}${month}${day}_${hours}${minutes}${seconds}`;
}
这个函数返回格式为YYYYMMDD_HHMMSS
的字符串,例如20230915_143022
,确保每次生成的文件名都是唯一的。
首先,需要为要截图的组件设置一个唯一的ID:
Stack() {
// 组件内容...
}.width(100)
.height(100)
.id('stack') // 设置组件ID为'stack'
使用componentSnapshot.get
方法获取指定ID组件的快照:
componentSnapshot.get("stack")
.then(async (pixmap: image.PixelMap) => {
if (pixmap !== null) {
// 处理获取到的快照
this.filePath = await this.saveFile(getContext(), pixmap);
console.log('保存路径', this.filePath);
}
}).catch((err: Error) => {
console.log("错误: " + err);
})
/**
* packing获取图片的ArrayBuffer数据,再使用fs库将图片写入文件
*/
async saveFile(context: Context, pixelMap: PixelMap): Promise<string> {
// 创建图像编码ImagePacker对象
const imagePackerApi = image.createImagePacker();
// 设置编码输出流和编码参数。format为图像的编码格式;quality为图像质量,范围从0-100,100为最佳质量
const options: image.PackingOption = { format: 'image/jpeg', quality: 100 };
// 图片写入的沙箱路径
const filePath: string = `${context.filesDir}/${getTimeStr()}.jpg`;
// 使用packing打包获取图片的ArrayBuffer
const data: ArrayBuffer = await imagePackerApi.packing(pixelMap, options);
let helper = photoAccessHelper.getPhotoAccessHelper(context);
let uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg');
let file = await fs.open(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
await fs.write(file.fd, data);
await fs.close(file.fd);
promptAction.showToast({ message: '已保存至相册!' });
return filePath;
}
image.createImagePacker()
创建图像编码器photoAccessHelper.getPhotoAccessHelper
获取相册访问助手fs.open
打开文件,设置为读写和创建模式promptAction.showToast
提示用户保存成功以下是组件快照获取和保存功能的完整实现:
// 导入必要模块
import componentSnapshot from '@ohos.arkui.componentSnapshot'
import image from '@ohos.multimedia.image'
import fs from '@ohos.file.fs';
import photoAccessHelper from "@ohos.file.photoAccessHelper";
import { promptAction } from "@kit.ArkUI";
/**
* 获取当前时间的拼接字符串,用于图片命名
*/
function getTimeStr(): string {
const now: Date = new Date();
const year: number = now.getFullYear();
const month: number = now.getMonth() + 1;
const day: number = now.getDate();
const hours: number = now.getHours();
const minutes: number = now.getMinutes();
const seconds: number = now.getSeconds();
return `${year}${month}${day}_${hours}${minutes}${seconds}`;
}
@Component
export struct MainPage {
// 组件状态和属性...
@State filePath: string = ''; // 保存图片后的文件路径
/**
* packing获取图片的ArrayBuffer数据,再使用fs库将图片写入文件
*/
async saveFile(context: Context, pixelMap: PixelMap): Promise<string> {
// 创建图像编码ImagePacker对象
const imagePackerApi = image.createImagePacker();
// 设置编码输出流和编码参数。format为图像的编码格式;quality为图像质量,范围从0-100,100为最佳质量
const options: image.PackingOption = { format: 'image/jpeg', quality: 100 };
// 图片写入的沙箱路径
const filePath: string = `${context.filesDir}/${getTimeStr()}.jpg`;
// 使用packing打包获取图片的ArrayBuffer
const data: ArrayBuffer = await imagePackerApi.packing(pixelMap, options);
let helper = photoAccessHelper.getPhotoAccessHelper(context);
let uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg');
let file = await fs.open(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
await fs.write(file.fd, data);
await fs.close(file.fd);
promptAction.showToast({ message: '已保存至相册!' });
return filePath;
}
build() {
// 组件布局...
Button('保存头像', { buttonStyle: ButtonStyleMode.EMPHASIZED })
.width(120)
.onClick(async () => {
// 保存图片
componentSnapshot.get("stack")
.then(async (pixmap: image.PixelMap) => {
if (pixmap !== null) {
// 图片写入文件
this.filePath = await this.saveFile(getContext(), pixmap);
console.log('保存路径', this.filePath, pixmap);
}
}).catch((err: Error) => {
console.log("错误: " + err);
});
});
}
}
HarmonyOS提供了强大的组件快照和图像处理能力,通过componentSnapshot
、image
和fs
等模块,可以轻松实现组件截图和保存功能。本教程详细介绍了从获取组件快照到保存图像的完整流程,希望能帮助开发者在实际应用中实现类似功能。