上一节我们利用Scroller实现了列表项的自动滚动功能,对于图像列表来说,被选做封面的图像需要保存为图片文件,以便向服务器上传封面图片。
由于avImageGenerator从视频提取的图像帧数据为image.PixelMap(位图格式),因此前面的图像转存操作就变成了把位图数据写入图片文件。那么根据沙箱文件的操作规范,可将完整的图片转存过程划分为下列三个步骤:
一、在沙箱目录下创建新文件并打开该文件
鸿蒙把文件操作能力封装到了Core File Kit(文件基础服务),并通过fileIo工具来调用文件操作函数。为此要在代码开头添加下面的导包语句,表示引入文件操作工具fileIo:
import { fileIo } from '@kit.CoreFileKit';
鸿蒙把创建文件和打开文件合并到了一起,调用open函数或者openSync函数,即可实现创建并打开文件的功能。注意,在调用open或者openSync的时候,模式参数要填“fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE”,表示指定路径若不存在文件就创建新文件,若已存在文件就打开原文件。示例代码如下:
let dstFile = fileIo.openSync(this.imagePath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
二、把位图数据打包写入第一步骤的新文件
鸿蒙把图片处理能力封装到了Image Kit(图片处理服务),并通过image工具来调用图片处理函数。image工具又包含下列常见的子工具:
(1)ImageSource类,提供获取图片信息、将图片解码为PixelMap或Picture、读取和修改图片属性的能力。支持解码的图片格式包括png、jpeg、bmp、gif、webp、dng、heic。
(2)ImagePacker类,提供将图片编码为压缩后的数据流或文件的能力。编码前需获取图片的ImageSource、PixelMap或Picture作为输入。支持编码的图片格式包括jpeg、webp、png、heic、gif。
(3)PixelMap类,位图对象,包含像素数据以及图片信息。可用于读取或写入像素数据,进行裁剪、缩放、平移、旋转、镜像等操作,并可直接传给Image组件用于显示。
可见位图数据属于PixelMap类,而位图数据的转存功能则由ImagePacker类实现,调用image工具的createImagePacker方法,即可获得ImagePacker类的对象实例。接着调用ImagePacker实例的packToFile,即可将位图数据写入指定句柄的文件中。示例代码如下:
imagePackerApi.packToFile(this.pixelMap, dstFile.fd, packOpts, (err: BusinessError) => {/* 这里可补充位图转存完成之后的其他操作 */if (err) { /* 打印失败日志 */ } else { /* 打印成功日志 */ }
})
三、写入完毕,关闭第一步打开的图片文件
调用fileIo工具的close函数或者closeSync函数,即可实现关闭文件的功能。示例代码如下:
fileIo.closeSync(dstFile);
综合上述三个步骤,可编写位图数据转存为图片文件的代码框架如下所示:
// 保存封面图片
saveCover() {let videoFileName = this.videoPath.toString().split('/').pop() as stringlet imageFileName = (videoFileName.split('.'))[0] + '_' + this.coverPos + '.jpeg'this.imagePath = `${this.context.cacheDir}/${imageFileName}`let dstFile = fileIo.openSync(this.imagePath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);// 转存为图片let imagePackerApi: image.ImagePacker = image.createImagePacker();let packOpts: image.PackingOption = { format: 'image/jpeg', quality: 90 };imagePackerApi.packToFile(this.pixelMap, dstFile.fd, packOpts, (err: BusinessError) => {fileIo.closeSync(dstFile);if (err) { /* 打印失败日志 */ } else { /* 打印成功日志 */ }})
}
下一篇文章会介绍如何把相册中的视频复制到沙箱目录。