更新记录
1.0.0(2026-10-09)
2026-10-09
- 首个版本发布
- Android 端:基于
BitmapFactory+Bitmap.compress实现压缩,inJustDecodeBounds只读尺寸、inSampleSize降采样防 OOM - iOS 端:基于
UIGraphicsImageRenderer重绘缩放 +UIImage.jpegData/pngData编码 - 鸿蒙端:基于
@kit.ImageKit的 PixelMap +image.createImagePacker编码 - 提供
compress/compressToBase64/resize/convertFormat/getImageInfo五个接口 - 返回压缩率与真实输出尺寸,便于业务侧判断是否需要二次压缩
- web 与小程序端降级到 Canvas 重绘路径,并提供
compressAsync异步接口 - webp 在无编码能力的平台(iOS / 鸿蒙 / API<30 的 Android)自动降级为 jpg,并在返回值中回写真实格式
平台兼容性
uni-app(3.99)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| √ | √ | √ | √ | √ | √ | √ | √ | √ |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | √ | √ | √ | √ | √ | √ | √ | √ | - | √ | × |
其他
| 多语言 | 暗黑模式 | 宽屏模式 | 蒸汽模式 |
|---|---|---|---|
| √ | √ | √ | × |
图片压缩(czg-imgcomp)
原生图片压缩与格式转换。App 端走 uts 原生实现(Android Bitmap / iOS UIGraphicsImageRenderer /鸿蒙 PixelMap),大图先降采样再压缩,避免一次性读入内存导致 OOM;web 与小程序端自动降级到 Canvas 重绘路径。
为什么不用现成方案
| 方案 | 问题 |
|---|---|
uni.compressImage |
只支持 jpg、不能指定质量、不返回压缩率、无法控制输出尺寸 |
| 引入 zopfli / mozjpeg wasm | 包体积大,小程序端加载慢,且压缩前仍要自己解码 |
直接调 Bitmap.compress |
直接对大图压缩极易 OOM;且缺采样、缺格式协商、缺结果度量 |
本插件的取舍:先按最长边降采样,再按目标质量重编码,与原生图片管线(Android decode→sample→encode)的做法一致,并额外返回压缩率与真实输出尺寸,方便业务侧判断是否需要二次压缩。
特性
- 原生实现:App 端不经过 JS 引擎,大图处理不卡 UI
- 降采样防OOM:Android 用
inSampleSize、鸿蒙用desiredSize、iOS 用UIGraphicsImageRenderer重绘,均在解码阶段降分辨率 - 只读尺寸不占内存:读取图片信息走
inJustDecodeBounds/getImageInfoSync,不分配像素缓冲 - 真实结果度量:返回压缩后字节数、尺寸、压缩率,
ratio可直接用于判断是否需要再压 - 格式协商:请求 webp 但平台无编码能力时(iOS、鸿蒙)自动降级为 jpg,并在返回值的
format中回写真实格式,不静默产出错格式 - 全端可用:App 端原生实现;web / 小程序降级到 Canvas,接口一致
安装
在插件市场搜索「图片压缩」或插件 ID czg-imgcomp,点击「使用 HBuilderX 导入插件」;或把 g-imgcomp 目录放入工程 uni_modules/ 下。
App 端需先用 HBuilderX 制作自定义基座,uts 插件才能运行。详见 uts 插件使用说明。
用法
import { compress, compressToBase64, resize, convertFormat, getImageInfo }
from '@/uni_modules/g-imgcomp/index.native.js'
// 1. 读图片信息(不占内存,可安全用于列表预加载)
const info = getImageInfo('/path/to/photo.jpg')
console.log(info.width, info.height, info.size, info.format)
// 2. 压缩到文件(质量 70 + 最长边不超过 1080)
const r = compress('/path/to/photo.jpg', {
quality: 70,
format: 'jpg',
maxEdge: 1080,
outPath: '/path/to/photo_min.jpg'
})
console.log(r.size) // 压缩后字节数
console.log(r.ratio) // 压缩率,如 0.18 表示压到原来的 18%
// 3. 压缩成 base64(直接塞进 JSON 字段)
const b64 = compressToBase64('/path/to/photo.jpg', {
quality: 60,
maxEdge: 640
})
// 4. 仅缩放,不重编码(保画质)
const rz = resize('/path/to/photo.jpg', 1280, '/path/to/photo_1280.jpg')
// 5. 格式转换
const cv = convertFormat('/path/to/photo.png', 'jpg', '/path/to/photo.jpg')
web / 小程序端
Canvas 导出本身是异步接口,所以压缩统一走 Promise:
import { compressAsync } from '@/uni_modules/g-imgcomp/index.js'
const r = await compressAsync('/path/to/photo.jpg', {
quality: 70,
format: 'jpg',
maxEdge: 1080
})
console.log(r.path) // 压缩后临时文件路径
web / 小程序端调用同步的
compress()会抛出错误并提示改用compressAsync(), 这是刻意设计——同步接口在非App 端没有等价实现,返回假结果比报错更糟。
API 清单
| 方法 | 签名 | 返回 |
|---|---|---|
getImageInfo |
(path: string) => ImageInfo |
{ width, height, size, format } |
compress |
(path: string, options: CompressOptions \| null) => CompressResult |
{ size, width, height, ratio, format, path } |
compressToBase64 |
(path: string, options: CompressOptions \| null) => string |
base64 字符串(无 dataURL 前缀) |
resize |
(path: string, maxEdge: number, outPath: string) => CompressResult |
同 compress |
convertFormat |
(path: string, format: string, outPath: string) => CompressResult |
同 compress |
compressAsync |
(path: string, options: CompressOptions \| null) => Promise<CompressResult> |
Promise,接口与 compress 一致 |
CompressOptions
| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
quality |
number | 80 | 质量 0~100;PNG 忽略此值 |
format |
string | 'jpg' |
'jpg' / 'png' / 'webp' |
maxEdge |
number | 0 | 目标最长边像素;0 表示不缩放,大于原图时不会放大 |
outPath |
string | '' |
输出路径;留空则自动生成 <原名>_min.<格式> |
filter |
string | 'high' |
缩放插值,'high' 清晰 / 'low' 更快 |
平台支持与能力差异
| 平台 | 实现 | 格式支持 |
|---|---|---|
| Android | BitmapFactory + Bitmap.compress |
jpg / png / webp |
| iOS | UIGraphicsImageRenderer + UIImage.jpegData |
jpg / png(无 webp 编码,请求 webp 自动降级为 jpg) |
| 鸿蒙 | @kit.ImageKit PixelMap + Packer |
jpg / png(无 webp 编码,请求 webp 自动降级为 jpg) |
| Web /小程序 | Canvas 重绘 + canvasToTempFilePath |
jpg / png |
Android 从 API 30 起原生支持 WebP 编码,低于 API 30 的设备请求 webp 时会回退为 jpg,返回值 format 为真实格式。若业务必须保证 webp,建议在 Android 端加最低版本约束:
"app-plus": { "android": { "minSdkVersion": 21 } }
错误码
| 码 | 含义 | 触发场景 |
|---|---|---|
| 40001 | EMPTY_PATH | 传入空路径或非字符串 |
| 40002 | BAD_OPTION | quality 越界、format 非法、maxEdge 为负、options 非对象;非 App 端调同步 compress |
| 40003 | FILE_NOT_FOUND | 路径不存在、无权限、或不是有效图片(尺寸为 0) |
| 50001 | UNSUPPORTED | 当前环境无 uni 对象且未注入原生实现 |
| 50002 | COMPRESS_FAIL | 解码或编码失败(文件损坏、格式不支持、磁盘写入失败) |
注意事项
ratio > 1表示压缩后反而变大了(典型场景:小图 +高 quality + PNG)。此时建议改小quality或不再压缩。- 二次压缩会累积画质损失。若目标是把 2MB 降到 200KB,一次把
quality设到 50~60通常优于两次各压80。 - PNG 无损,压缩只能靠缩小尺寸来减小体积。需要减小体积请用 jpg。
- 输入路径为 App 本地文件路径(
plus.io.convertLocalFileSystemURL或uni.saveFile的返回值),不是网络 URL。
价格
| 授权类型 | 价格 |
|---|---|
| 普通授权(regular) | ¥19.90 |
| 源码授权(sourcecode) | ¥99.00 |
普通授权版由 DCloud 对 uts 源码加密保护,运行时经云端解密编译;源码授权版提供完整 uts 源码,可自行修改与扩展,同样享受后续版本升级。
隐私说明
本插件全部图片处理在本机完成,不联网、不采集、不上传任何图片或数据。插件不主动读取相册与存储目录,输入完全由调用方通过参数传入。隐私声明详见 package.json 的 dcloudext.declaration。
更新日志
开源协议
MIT

收藏人数:
购买源码授权版(
试用
赞赏(0)
下载 2
赞赏 0
下载 12663374
赞赏 1955
赞赏
京公网安备:11010802035340号