HarmonyOS:如何将图片转为PixelMap并进行图片缓存策略
前言:在HarmonyOS项目开发中,我们使用Ark-Ts语言开发项目。我们有个功能是拍照,除了正常显示出来,并且上传服务器。我在开发过程中,遇到的问题是,如果离开这个页面再回到当前页面仍要显示图片,那我的思路就是存储在沙盒,重新回到这个页面先去沙盒里面查找照片,如果找到就显示出来。
流程图:
1.模拟拍照:
模拟拍照方法
takePhoto(){
let pixelMap1 = await SnapshotUtil.snapshot()
//添加水印信息(此处省略)
//调用步骤2.
//照片存储到本地,并返回路径
let filePath:string = await WinPixelImageTool.asyncSavePixelImageToFileCache(waterMarkPixelMap);
//存储照片存储沙盒路径
let imageKey = '自定义key值'
PreferencesManager.set(imageKey,filePath);
}
/**
* 获取窗口截图,使用Promise异步回调。
* @param windowClass 不传默认截图主窗口
* @returns
*/
static async snapshot(windowClass?: window.Window): Promise<image.PixelMap> {
return (windowClass ?? AppUtil.getMainWindow()).snapshot();
}
2.生成图片存储路径
static asyncSavePixelImageToFileCache(pixelIamge:PixelMap){
return new Promise<string>((resolve)=>{
const imagePackerApi: image.ImagePacker = image.createImagePacker();
let packOpts : image.PackingOption = { format:"image/png", quality:100 };
const context : Context = AppUtil.getContext();
let fileName = DateUtil.getTodayTime().toString();
let path : string = context.cacheDir + `/sfa`;
if (!FileUtil.accessSync(path)) {
FileUtil.mkdirSync(path)
}
path = `${path}/pixel_map_${fileName}.png`
let file = fs.openSync(path, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE);
imagePackerApi.packToFile(pixelIamge, file.fd, packOpts,(error: BusinessError): void => {
if (error) {
resolve('')
}else {
// let fileUriPath = fileUri.getUriFromPath(path);
resolve(path)
}
})
})
}
//存储方法
static set(key: string, value: dataPreferences.ValueType) {
if (context==undefined) {
context = AppUtil.getContext()
}
let preferences = dataPreferences.getPreferencesSync(context, { name: preferencesName });
preferences?.putSync(key, value);
preferences?.flush();
}
3.如何将图片转为PixelMap并且显示出来,方法如下:
/*
- 沙盒目录下的照片转为image.PixelMap
- imageId是存储照片沙盒路径的key
- localImagePath 是照片的存储沙盒路径
*/
//通过Imagekey获取图片,比如门头照显示就是此方法
static getImageByImageId(imageId:string):Promise<image.PixelMap> {
return new Promise<image.PixelMap>(async (resolve,reject) => {
let localImagePath = PreferencesManager.get(imageId) as string;
if (localImagePath&&localImagePath.length>0) {
let tmpImagePixelMap = await WinImagePixelMapUtils.getImagePixelMapWithFilePath(localImagePath);
resolve(tmpImagePixelMap.pixelMap);
}else {
reject();
}
})
}
//WinImagePixelMapUtils类
static async getImagePixelMapWithFilePath(filePath:string){
let imageSource = image.createImageSource(filePath);
return await imageSource2PixelMap(imageSource);
}
export async function imageSource2PixelMap(imageSource: image.ImageSource): Promise<ImagePixelMap> {
const imageInfo: image.ImageInfo = await imageSource.getImageInfo();
const height = imageInfo.size.height;
const width = imageInfo.size.width;
const options: image.DecodingOptions = {
editable: true,
desiredSize: { height, width }
};
const pixelMap: PixelMap = await imageSource.createPixelMap(options);
const result: ImagePixelMap = { pixelMap, width, height };
return result;
}
getImageByImageId
通过此方法找到沙盒里面的图片,
使用Image组件可以直接加载tmpImagePixelMap.pixelMap