HarmonyOS NEXT图片压缩(支持fd,uri,网络图片,沙箱路径,base64,ArrayBuffer)

前言

在移动端领域,图片压缩基本是绕不过去的需求,尤其是微信分享对图片有大小限制。而高频使用图片压缩的原因无非以下几点原因:

1:性能优化,大尺寸图片导致内存占用飙升,易引发应用卡顿、闪退(尤其低端机型),压缩可降低渲染压力。

2:流量敏感,未压缩图片消耗用户超额流量,移动网络下加载缓慢,影响弱网用户体验。

3:存储限制,本地缓存大图快速占满手机存储空间,导致用户主动清理或卸载应用。

4:成本控制,服务器带宽和云存储费用与图片体积正相关,压缩可降低企业运营成本。

5:平台规则适配,社交媒体/文件上传接口普遍存在图片尺寸限制(如微信头像),压缩可规避上传失败。

6:响应速度提升,压缩后图片传输耗时减少50%以上,显著缩短用户等待时间。

7:视觉平衡需求,移动端屏幕物理尺寸有限,超高分辨率图片难以被肉眼感知,压缩可剔除冗余像素数据。

本质矛盾:移动端资源有限性(硬件/网络/存储)与高质量图片需求之间的冲突,压缩是技术妥协的最优解

而图片压缩又分2种

1:质量压缩(不改变图片分辨率的情况下压缩图片文件大小)
2:分辨率压缩(改变图片分辨率,分辨率压缩时也会改变文件大小)

简单使用示例(支持文件大小和图片分辨率大小压缩)

public compress(context:Context){
  // 此处换成实际的图片uri
  const imageData = 'file://com.example.xxx/xxx.jpg'
  // 支持fd、uri、沙箱路径、图片url、base64图片、ArrayBuffer数据
  HMImage.compress(context)
  .start([imageData])
  .then((result: CompressResult) => {
    // 本次压缩是否全部成功
    const isAllSuccess = result.isAllSuccess
    // 本次压缩成功的数据
    const successData = result.successData
    // 本次压缩失败的数据
    const failData = result.failData
  }).catch((error: BusinessError) => {
  
  })
}

图片压缩实现方法介绍

1:质量压缩

const imagePacker: image.ImagePacker = image.createImagePacker()
// format:图片压缩后的目标格式
// quality:输出图片质量的参数,该参数仅对JPEG图片和HEIF图片生效。取值范围为0-100。
// 0质量最低,100质量最高,质量越高生成图片所占空间越大。WebP、PNG等图片均为无损编码
const packOpts: image.PackingOption = { format: 'image/webp', quality: 70 }
const imagePath = 'xxxx' //实际的图片沙箱路径
const imageSource = image.createImageSource(imagePath)
const result:ArrayBuffer = await imagePacker.packToData(imageSource, packOpts)
// 最后将压缩得到的ArrayBuffer类型的数据保存至本地,然后就完成了图片质量压缩
// 是不是很简单?其实就是官网提供的api,只负责调用就实现了

2:分辨率压缩

// 分辨率压缩的目标大小,比如500x500的图片,压缩成100X100的图片
let options: image.DecodingOptions = {
  desiredSize: {
    width: 100,
    height: 100
  }
}
const imagePath = 'xxxx' //实际的图片沙箱路径
const imageSource = image.createImageSource(imagePath)
// 这里进行分辨率压缩返回一个图像像素类PixelMap,
// 后续在通过packToData无损压缩返回ArrayBuffer数据
const pixelMap = imageSource.createPixelMapSync(options)

const imagePacker: image.ImagePacker = image.createImagePacker()
const packOpts: image.PackingOption = { format: 'image/webp', quality: 100 }
const result:ArrayBuffer = await imagePacker.packToData(pixelMap, packOpts)
// 最后将压缩得到的ArrayBuffer类型的数据保存至本地,然后就完成了图片分辨率压缩
// 是不是很简单?其实就是官网提供的api,只负责调用就实现了

ArrayBuffer数据保存至沙箱方法

// 需要保存文件的路径
const filePath="xxxx"
let fileFd =fileIo.openSync(filePath, fileIo.OpenMode.CREATE 
                            | fileIo.OpenMode.WRITE_ONLY 
                            | fileIo.OpenMode.TRUNC).fd
fileIo.writeSync(fileFd, arrayBuffer)
fileIo.closeSync(fileFd)

图片压缩库介绍(源码在文末)

支持的数据类型:fd,uri,图片沙箱路径,图片网络地址,base64图片,ArrayBuffer。
支持批量压缩,提供压缩进度监听。

HMImageUtils额外提供

1:fd转ArrayBuffer、UintArray方法
2:uri转ArrayBuffer、UintArray方法
3:沙箱路径转ArrayBuffer、UintArray方法
4:ArrayBuffer转UintArray方法

下载安装

中心仓库地址

ohpm install @zhongrui/hm_image

导入模块

import { HMImage, CompressImageOption, CompressResult } from "@zhongrui/hm_image";

图片压缩

public compress(context:Context){
  // 此处换成实际的图片uri
  const imageData = 'file://com.example.xxx/xxx.jpg'
  // 支持fd、uri、沙箱路径、图片url、base64图片、ArrayBuffer数据
  HMImage.compress(context)
     // 打开调试模式,输出日志
    .setDebug(true)
    .setProgressListener((progress:number,total:number)=>{
        //压缩进度,progress:压缩成功的数量,total:总数量
    })
    .start([imageData]).then((result: CompressResult) => {
    // 本次压缩是否全部成功
    const isAllSuccess = result.isAllSuccess
    // 本次压缩成功的数据
    const successData = result.successData
    // 本次压缩失败的数据
    const failData = result.failData
    // 处理完业务操作之后,调用delete()方法可以删除本次压缩保存的沙箱图片
    result.delete()
    // 处理完业务操作之后,调用deleteAll()方法可以删除所有压缩保存在沙箱目录的图片,效果和HMImage.deleteAllCompressImage(context)一致
    result.deleteAll()
  }).catch((error: BusinessError) => {
    const code = error.code
    const message = error.message
    console.info("compress err code:" + code + ",message:" + message)
  })
}
compress

compress(context: Context, option?: CompressImageOption)
设置压缩参数

参数名类型是否必填说明
contextContext应用上下文
optionCompressImageOption图片压缩选项

CompressImageOption

参数名类型是否必填说明
maxWidthnumber限制图片压缩后的最大宽度不超过maxWidth,单位:px
maxHeightnumber限制图片压缩后的最大高度不超过maxHeight,单位:px
scalenumber图片压缩时设置的分辨率缩放比例取值范围:(0,1]
maxFileSizenumber设置图片压缩后的文件大小不超过maxFileSize,单位:byte
ignoreFileSizenumber图片大小如果小于等于ignoreFileSize,则不压缩,单位:byte
targetDirstring设置图片保存的目录
qualitynumber图片压缩的质量,取值范围:(0,100],默认值:70
qualityStepnumber如果图片压缩后的文件大小超过maxFileSize,quality会依次减少qualityStep再进行压缩
compressNumnumber同时压缩图片的多线程数量,默认值:8
imageFormatCompressionImageFormat取值:JPEG,WEBP,PNG,HEIC,HEIF,默认值:CompressionImageFormat.WEBP
start

start(image: ImageDataType[]): Promise< CompressResult >;
参数:

参数名类型是否必填说明
imageImageDataType[]图片数据,支持string或number或ArrayBuffer类型,可以是fd,uri,url,沙箱路径,base64

返回值:

参数名类型说明
isAllSuccessboolean图片是否全部压缩成功
successDataCompressImageData[]压缩成功的图片数据
failDataCompressImageData[]压缩失败的图片数据
deletefunction删除本次图片压缩文件的方法
deleteAllfunction删除所有图片压缩文件的方法

CompressImageData

参数名类型说明
codenumber错误码
messagestring错误提示信息
originImageDataType原始图片数据
originSizenumber原始图片文件大小,单位:byte
fileNamestring原始图片缓存到沙箱目录的文件名
filePathstring原始图片缓存到沙箱目录的文件路径
compressFileNamestring压缩后的图片文件名
compressFilePathstring压缩后的图片文件路径
compressFileSizenumber压缩后的图片文件大小,单位:byte

CompressImageData.code错误码

错误码说明
1成功
-1内部错误
1001参数错误
1002原始图片复制到沙箱目录错误
1003检查图片大小错误
1005剩余空间不足
1006创建imageSource失败
1007分辨率压缩失败
1008质量压缩失败
1009保存和压缩过程错误
1010网络图片地址为空
1011获取网络图片大小错误
1012下载网络地址错误

注意:start().then().catch((error: BusinessError) => {})中的BusinessError错误码需要另行处理,可参考官方文档

deleteAllCompressImage

删除所有图片压缩保存到本地的文件的方法

// 删除所有压缩保存在沙箱目录的图片
HMImage.deleteAllCompressImage(context)

let targetDir='/data/xxxx/haps/entry/files'
// 如果压缩图片时CompressImageOption参数有设置targetDir,这里可以传入otherDir一起删除
HMImage.deleteAllCompressImage(context,targetDir)
  
let otherDir=['/data/xxxx/haps/entry/files','/data/xxxx/haps/entry/cache']
// 除了删除默认缓存目录,还需要删除其他多个目录
HMImage.deleteAllCompressImage(context,...otherDir)

参数:

参数名类型是否必传说明
contextContext应用上下文
dirPath…string[]其他目录

HMImageUtils

// fd、uri、沙箱路径文件转ArrayBuffer
HMImageUtils.fileToArrayBuffer(file: number | string)

// base64数据转ArrayBuffer
HMImageUtils.base64ToArrayBuffer(base64Image: string)

// fd、uri、沙箱路径、base64、ArrayBuffer数据转Uint8Array
HMImageUtils.fileToUint8Array(file: ImageDataType)

中心仓库地址
源码地址

历史文章

HarmonyOS NEXT多环境+多渠道+自定义路径输出+自定义名称一键打app和hap包
HarmonyOS NEXT一行代码实现任意处弹窗
HarmonyOS NEXT数据列表加载更多(无需监听列表滑到最底部)
HarmonyOS NEXT下拉刷新+上拉加载(纵向横向都支持)(v1+v2装饰器)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Harmony钟睿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值