HarmonyOS Next 将ArrayBuffer压缩到指定大小并转化为base64返回
鸿蒙开发中图片压缩至固定大小的实现
在鸿蒙应用开发中,图片压缩是一个常见的需求,尤其是在需要将图片上传到服务器或存储到本地时。为了满足项目中对图片大小的严格要求,我们需要将图片压缩到固定大小。本文将详细介绍如何在鸿蒙开发中实现这一功能,包括图片压缩、大小检查以及循环压缩直至达到目标大小的实现方法。
1. 图片压缩的基本原理
鸿蒙系统提供了 image.ImagePacker 类,用于对图片进行压缩。通过设置图片格式和质量参数,可以实现对图片的压缩。然而,直接设置质量参数并不能保证压缩后的图片大小符合预期,因此需要结合循环检查和逐步调整质量参数的方式来实现目标。
2. 实现步骤
以下是实现图片压缩至固定大小的详细步骤:
(1)初始化图片数据和目标大小
首先,我们需要获取待压缩的图片数据和目标大小:
let bitmap: ArrayBuffer; // 需要压缩的图片数据
let compressSize: number; // 目标大小(单位:KB)
let considerBase64: boolean; // 是否考虑 Base64 编码的影响
let result = ''; // 压缩后的结果
(2)创建图片源和压缩器
使用 image.createImageSource 和 image.createImagePacker 创建图片源和压缩器:
if (bitmap) {
try {
let imageSource = image.createImageSource(bitmap);
let packer = image.createImagePacker();
let packerData = await packer.packing(imageSource, {
format: 'image/jpeg',
quality: 100 // 初始质量设置为 100
});
(3)考虑 Base64 编码的影响
如果需要对压缩后的图片进行 Base64 编码,则需要考虑 Base64 编码会将字节数扩大约 4/3 倍的影响:
if (considerBase64 && compressSize > 0) {
compressSize = Math.ceil(compressSize * 3.0 / 4.0 - 0.5);
}
(4)循环压缩直至达到目标大小
通过 while 循环逐步降低图片质量,直到压缩后的图片大小小于或等于目标大小:
let optionQuality = 90; // 初始质量设置为 90
while (compressSize > 0
&& packerData.byteLength / 1024 > compressSize
&& optionQuality > 0) {
let whilePacker = image.createImagePacker();
let whileImageSource = image.createImageSource(packerData);
packerData = await whilePacker.packing(whileImageSource, {
format: 'image/jpeg',
quality: optionQuality
});
optionQuality -= 10; // 每次降低质量 10
}
(5)将压缩后的图片转换为 Base64 字符串
最后,将压缩后的图片数据转换为 Base64 字符串:
result = buffer.from(packerData).toString('base64');
(6)错误处理
在压缩过程中,可能会遇到各种错误(如图片格式不支持、内存不足等),需要进行捕获和处理:
} catch (error) {
hilog.error(0x0000, 'error: ' + JSON.stringify(error), '%{public}s');
}
3. 完整代码示例
以下是一个完整的代码示例,包括图片压缩、大小检查和循环压缩的实现:
import image from '@ohos.multimedia.image';
import hilog from '@ohos.hilog';
import buffer from '@ohos.buffer';
async function compressImageToSize(bitmap: ArrayBuffer, compressSize: number, considerBase64: boolean): Promise<string> {
let result = '';
if (bitmap) {
try {
// 创建图片源和压缩器
let imageSource = image.createImageSource(bitmap);
let packer = image.createImagePacker();
let packerData = await packer.packing(imageSource, {
format: 'image/jpeg',
quality: 100 // 初始质量设置为 100
});
// 考虑 Base64 编码的影响
if (considerBase64 && compressSize > 0) {
compressSize = Math.ceil(compressSize * 3.0 / 4.0 - 0.5);
}
// 循环压缩直至达到目标大小
let optionQuality = 90; // 初始质量设置为 90
while (compressSize > 0
&& packerData.byteLength / 1024 > compressSize
&& optionQuality > 0) {
let whilePacker = image.createImagePacker();
let whileImageSource = image.createImageSource(packerData);
packerData = await whilePacker.packing(whileImageSource, {
format: 'image/jpeg',
quality: optionQuality
});
optionQuality -= 10; // 每次降低质量 10
}
// 将压缩后的图片转换为 Base64 字符串
result = buffer.from(packerData).toString('base64');
} catch (error) {
hilog.error(0x0000, 'error: ' + JSON.stringify(error), '%{public}s');
}
}
return result;
}
4. 注意事项
在实际开发中,需要注意以下几点:
(1)性能优化
- 如果图片较大,循环压缩可能会占用较多 CPU 资源,建议在子线程中执行压缩操作。
- 可以设置最大循环次数,避免无限循环。
(2)图片质量
- 逐步降低图片质量可能会导致图片失真,需要根据实际需求调整质量参数。
(3)错误处理
- 捕获并处理压缩过程中可能出现的异常,确保程序的健壮性。
5. 总结
通过以上方法,我们可以在鸿蒙开发中实现将图片压缩至固定大小的功能。这种方法结合了图片质量调整和大小检查,能够有效满足项目中对图片大小的严格要求。希望本文的介绍能为您的开发工作提供帮助!

浙公网安备 33010602011771号