鸿蒙NEXT压缩与解压全攻略:从图片优化到文件处理
开发者的实用指南,掌握鸿蒙系统的压缩技术
在日常应用开发中,压缩与解压功能无处不在。无论是处理用户上传的图片,还是减少网络传输数据量,高效压缩技术都至关重要。本文将带你全面了解鸿蒙NEXT中的压缩与解压能力,并通过实际代码示例展示如何实现这些功能。
鸿蒙NEXT压缩技术概述
鸿蒙NEXT提供了多层次的压缩解决方案,从官方的@ohos.zlib
模块到三方库支持,涵盖了多种压缩格式和场景需求。
支持的压缩格式包括:
压缩格式 | 简介 | 系统支持情况 |
---|---|---|
ZIP | 普及率高,适用范围广,压缩速度较快 | ArkTS支持,可通过zlib实现 |
RAR | 相比ZIP提供更好的压缩率,但速度较慢 | 三方库支持 |
7Z | 压缩率最大,但速度最慢 | 三方库支持 |
GZIP | 使用gzip算法极大减少文件体积 | 三方库支持 |
Brotli | 无损压缩算法,主要压缩Internet数据 | 三方库支持 |
TAR | 简单的归档文件,仅是文件封装 | 三方库支持 |
数据来源:
图片压缩实战
图片压缩是应用开发中最常见的需求之一,特别是在处理用户上传图片时。鸿蒙NEXT提供了强大的图片压缩能力,支持jpeg、webp、png等格式。
实现思路
拉起图库选择图片:使用
photoAccessHelper.PhotoViewPicker
创建图库选择器实例读取图片数据:将图片数据读取到buffer,创建图片源实例
压缩处理:通过
packing
(质量压缩)和scale
(尺寸压缩)方式进行压缩保存图片:将压缩后的图片保存到图库
核心代码实现
typescript
async selectPhotoFromAlbum() {// 创建图库选项实例const photoSelectOptions = new photoAccessHelper.PhotoSelectOptions();photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;photoSelectOptions.maxSelectNumber = 1;// 创建图库选择器实例const photoViewPicker = new photoAccessHelper.PhotoViewPicker();// 选择图片photoViewPicker.select(photoSelectOptions).then((photoSelectResult) => {this.uris = photoSelectResult.photoUris;this.photoCount = this.uris.length;if (this.photoCount > 0) {const ALBUM_PATH: string = photoSelectResult.photoUris[0];// 读取选择图片的bufferconst file = fs.openSync(ALBUM_PATH, fs.OpenMode.READ_ONLY);this.beforeCompressByteLength = fs.statSync(file.fd).size;fs.closeSync(file);}}).catch((err: BusinessError) => {hilog.error(0x0000, TAG, `PhotoViewPicker.select failed: error code: ${err.code}, message: ${err.message}.`);}) }
手动模式压缩图片:
typescript
manualCompression() {const ALBUM_PATH: string = this.uris[0];const file = fs.openSync(ALBUM_PATH, fs.OpenMode.READ_ONLY);let buffer = new ArrayBuffer(fs.statSync(file.fd).size);fs.readSync(file.fd, buffer);fs.closeSync(file);const decodingOptions: image.DecodingOptions = { editable: true };const imageSource: image.ImageSource = image.createImageSource(buffer);imageSource.createPixelMap(decodingOptions).then(async (originalPixelMap: image.PixelMap) => {// 使用scale对图片进行缩放,使用packing进行图片质量压缩// ... 压缩逻辑}); }
压缩模式选择
鸿蒙NEXT提供两种压缩模式:
自动模式:设置压缩目标大小,系统自动调整参数压缩到最接近但不超过目标大小
优先压缩质量:先调整图片质量,不足时再调整尺寸
优先压缩尺寸:先调整图片尺寸,同时可设置最低图片质量
手动模式:手动调整图片质量和尺寸参数进行精确控制
文件压缩与解压
除了图片压缩,鸿蒙NEXT还提供了完整的文件压缩与解压能力,支持对沙箱目录中的文件进行操作。
在Worker线程中压缩文件
为了避免阻塞主线程,建议在Worker子线程中执行压缩操作。
实现步骤:
创建Worker线程文件
在主线程中创建Worker实例
通过
postMessage()
向Worker线程发送压缩参数在Worker线程中使用
zlib.compressFile
接口压缩文件返回压缩结果到主线程
核心代码:
在主线程中:
typescript
// 创建Worker实例 let workerInstance: worker.ThreadWorker = new worker.ThreadWorker('@compressfile/ets/worker/Worker.ets');// 向Worker线程发送消息 workerInstance.postMessage({pathDir: this.pathDir,compressZipPath: this.compressZipPath,beCompressFileDir: this.beCompressFileDir });
在Worker.ets中:
typescript
const workerPort: ThreadWorkerGlobalScope = worker.workerPort;workerPort.onmessage = (e: MessageEvents): void => {const pathDir: string = e.data.pathDir; // 沙箱目录const rawfileDirName: string = e.data.beCompressFileDir; // 被压缩文件目录名const outFilePath: string = `${pathDir}/${e.data.compressZipPath}`; // 压缩包输出路径// 检查并创建输出目录fs.access(outFileDir, (err: BusinessError, res: boolean) => {if (!res) {fs.mkdirSync(outFileDir);}});let options: zlib.Options = {level: zlib.CompressLevel.COMPRESS_LEVEL_DEFAULT_COMPRESSION,memLevel: zlib.MemLevel.MEM_LEVEL_DEFAULT,strategy: zlib.CompressStrategy.COMPRESS_STRATEGY_DEFAULT_STRATEGY};// 压缩文件zlib.compressFile(`${pathDir}/${rawfileZipName}`, outFile, options, (errData: BusinessError) => {if (errData !== null) {logger.error(TAG, `compress failed with error message: ${errData.message}, error code: ${errData.code}`);} else {workerPort.postMessage(outFileDir);}}) }
文件解压
解压过程与压缩类似,使用zlib.decompressFile
接口:
typescript
// 在Worker线程中解压文件 zlib.decompressFile(compressedFilePath, outFileDir, (errData: BusinessError) => {if (errData !== null) {logger.error(TAG, `decompress failed with error message: ${errData.message}, error code: ${errData.code}`);} else {workerPort.postMessage(outFileDir);} })
不同路径下的文件处理
鸿蒙NEXT支持对不同资源路径下的文件进行压缩与解压:
rawfile目录下的文件:通过
resourceManager.getRawFileContent
获取文件内容,然后拷贝到沙箱路径再进行压缩操作resfile目录下的文件:通过
getContext().resourceDir
获取路径,直接进行压缩操作
第三方压缩软件集成
除了使用鸿蒙原生的压缩能力,还可以集成第三方压缩软件。2345好压作为国内知名压缩软件,已完成鸿蒙电脑系统的全面适配升级,成为首批鸿蒙合作伙伴。
2345好压鸿蒙版的特点:
支持ZIP、7Z、RAR、GZ等39种压缩格式
单个大文件压缩速度比Windows版本提升8倍以上
多文件目录复杂场景下压缩速度提升至12倍
深度融合鸿蒙分布式特性,支持多设备协同
性能优化建议
使用Worker线程:将压缩/解压操作放在Worker子线程中,避免阻塞主线程
合理选择压缩参数:
图片压缩时,根据需求选择优先质量还是优先尺寸
设置合适的压缩级别,平衡压缩比和速度
内存管理:及时释放不再使用的压缩数据,避免内存泄漏
错误处理:完善的错误处理机制,确保压缩失败时应用仍能正常运行
常见问题与解决方案
问题一:zlib.decompress后需要释放资源吗?
解答:鸿蒙NEXT的zlib模块会自动管理内存,但如果在解压后出现异常,可能是上下文未完全清除,建议重启应用或确保每次解压使用新的实例。
问题二:压缩文件输出路径有特殊字符导致失败
解答:压缩文件输出路径不能包含特殊字符,请使用标准路径格式。
问题三:图片压缩达不到设定的目标大小
解答:检查参数配置是否合理,如scale每次缩小倍数设置较大但压缩目标大小设置很小时,可能出现此情况。可调整参数重新尝试。
总结
鸿蒙NEXT提供了全面而强大的压缩与解压能力,从图片优化到文件处理,涵盖了应用开发中的常见场景。通过本文的介绍,相信你已经对鸿蒙平台的压缩技术有了全面了解,并能够在实际项目中灵活运用这些能力。
无论是使用原生API还是第三方库,鸿蒙NEXT都能为你的应用提供高效、稳定的压缩解决方案,帮助优化应用性能,提升用户体验。