HarmonyOS 鸿蒙Next 图片压缩场景化代码
HarmonyOS 鸿蒙Next 图片压缩场景化代码
介绍
从相册中批量选择图片并通过imagePackerApi进行压缩,压缩后转成base64格式,可用于arkui或则H5中进行图片展示。
效果图
使用说明
打开应用,展示选择图片并压缩按钮,点击按钮,拉起系统相册,相册里选择图片或者拍照获取图片,选择完毕后点击完成,即可返回应用主页面,展示压缩后的图片。
实现思路
- 构造selectAndCompressPicture()函数,执行以下操作:
- 首先将this.pictures数组清空.
- 调用PictureUtils.selectPicture()方法,等待其返回结果,并将结果存储在selectResult中。
- 从selectResult中获取photoUris数组,遍历该数组。
- 对于每个uri,调用PictureUtils.compressPicture方法进行图片压缩,压缩格式为image/jpeg,质量为10。
- 压缩完成后,将压缩后的ArrayBuffer数据转换为base64字符串,并添加 data:image/png;base64, 前缀,存储到this.pictures数组中。
async selectAndCompressPicture() {
this.pictures = [];
let selectResult: photoAccessHelper.PhotoSelectResult = await PictureUtils.selectPicture(2);
let pictureUriArr: Array<string> = selectResult.photoUris;
pictureUriArr.forEach(uri => {
PictureUtils.compressPicture(uri, "image/jpeg", 10).then((data: ArrayBuffer) => {
// 将图片转成base64
let base64Str = buffer.from(data).toString('base64')
let resultBase64Str = "data:image/png;base64," + base64Str
this.pictures.push(resultBase64Str)
})
});
}
- 遍历this.pictures数组中的元素,并为每个元素创建一个Image对象,以此来加载展示压缩后返回的图片。
ForEach(this.pictures, (uri: string) => {
Image(uri)
.width('90%')
.height('50%')
.padding({ top: 30 })
}, (item: string) => item)
- 构造selectPicture()函数,用于选择图片。函数接收一个数字参数selectNumber,表示要选择的图片数量。具体实现过程为:
- 创建一个photoAccessHelper.PhotoSelectOptions实例photoSelectOptions,并设置其MIMEType为photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE,表示只选择图像类型的媒体文件。
- 将photoSelectOptions的maxSelectNumber属性设置为selectNumber,以指定最大选择数量。
- 创建一个photoAccessHelper.PhotoViewPicker实例photoPicker。
- 调用photoPicker.select(photoSelectOptions) 方法进行图片选择,并使用await等待结果,最终将结果作为 Promise<photoAccessHelper.PhotoSelectResult> 类型返回。
static async selectPicture(selectNumber: number): Promise<photoAccessHelper.PhotoSelectResult> {
let photoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
// 设置要选择的媒体文件类型
photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
// 设置选择文件最大数量
photoSelectOptions.maxSelectNumber = selectNumber;
let photoPicker = new photoAccessHelper.PhotoViewPicker();
return await photoPicker.select(photoSelectOptions)
}
- 构造compressPicture()函数,用于压缩图片。具体实现过程为:
- 首先,以只读模式打开文件系统中 pictureUri 对应的文件,使用 fs.openSync 方法,并获取文件描述符 file。
- 使用 fs.statSync 方法根据文件描述符获取文件大小,并将其存储在 size 变量中。
- 创建一个大小为 size 的 ArrayBuffer,并使用 fs.readSync 方法将文件内容读取到 buf 中。
- 关闭文件,使用 fs.closeSync 方法。
- 使用 image.createImageSource 方法将 buf 转换为图像源。
- 创建 imagePackerApi 作为图像打包器,通过 image.createImagePacker 方法。
- 创建 packOpts 对象,包含压缩格式 format 和压缩质量 quality。
- 调用 imagePackerApi.packing 方法对图像源进行压缩,并使用 await 等待结果,最终将结果作为 Promise 类型返回。
static async compressPicture(pictureUri: string, format: string, quality: number): Promise<ArrayBuffer> {
let file = fs.openSync(pictureUri, fs.OpenMode.READ_ONLY);
let size = fs.statSync(file.fd).size;
let buf = new ArrayBuffer(size);
fs.readSync(file.fd, buf);
fs.closeSync(file);
let imageSource = image.createImageSource(buf);
<span class="hljs-keyword">const</span> imagePackerApi: image.ImagePacker = image.createImagePacker();
<span class="hljs-keyword">let</span> packOpts: image.PackingOption = { format: format, quality: quality };
<span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> imagePackerApi.packing(imageSource, packOpts)
}
工程目录
entry/src/main/ets/
|---entryability
| |---EntryAbility.ets
|---log
| |---logger.ets // 打印组件
|---pages
| |---Index.ets // 入口页面
|---utils
| |---PictureUtils.ets // 图片工具类,包含图片选择及图片压缩
约束与限制
- 手机ROM版本:NEXT 5.0
- IDE:DevEco Studio 5.0.3.900
- API:API 12
更多关于HarmonyOS 鸿蒙Next 图片压缩场景化代码的实战教程也可以访问 https://www.itying.com/category-93-b0.html
1 回复
更多关于HarmonyOS 鸿蒙Next 图片压缩场景化代码的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙Next系统中,针对图片压缩的场景化代码可以通过使用MediaCodec
API实现高效编码压缩。以下是一个简化的代码示例,用于将图片进行压缩:
#include <media/MediaCodec.h>
#include <utils/BitmapUtils.h>
#include <fstream>
void compressImage(const std::string& inputPath, const std::string& outputPath, int quality) {
// 读取图片文件
OHOS::Media::Bitmap bitmap = OHOS::Utils::BitmapUtils::DecodeFile(inputPath);
// 初始化MediaCodec进行压缩
OHOS::Media::MediaCodec codec("video/jpeg");
codec.configure(nullptr, 0, nullptr, 0);
codec.createInputSurface();
// 绘制Bitmap到Surface,进行编码
// 注意:这里省略了具体的绘制代码,需使用Canvas等API
// 获取编码后的数据
OHOS::Media::BufferInfo bufferInfo;
std::vector<uint8_t> compressedData;
codec.dequeueOutputBuffer(bufferInfo, -1);
compressedData.resize(bufferInfo.size);
codec.read(compressedData.data(), bufferInfo.offset, bufferInfo.size);
codec.releaseOutputBuffer(bufferInfo.index, false);
// 保存压缩后的数据到文件
std::ofstream outFile(outputPath, std::ios::binary);
outFile.write(reinterpret_cast<const char*>(compressedData.data()), compressedData.size());
outFile.close();
}
// 如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html
请注意,此代码示例为简化版,实际使用中需要处理错误检查、资源释放等细节。