写在前面
前段时间在研究如何高效压缩图片,搜索了国内外大量技术文章,最终选择了谷歌的squoosh
项目,其他项目问题多,不维护等原因我试过之后都放弃了。有兴趣的可以看看这个网站 squoosh[1]
一、使用场景
-
1s
截屏一次,将图像压缩后的Buffer
通过网络传输
二、安装
npm install @squoosh/lib
三、实现
-
因为文档较少,并且很少有
TypeScript
方式的使用例子,推荐看这个源代码squoosh index.ts[2] -
直接贴我写的完整实现代码(可以直接拿来用)
// @ts-ignore
import {ImagePool} from '@squoosh/lib';
import {cpus} from 'os';
//https://github.com/GoogleChromeLabs/squoosh/blob/dev/libsquoosh/src/index.ts
export type EncodeResult = {
optionsUsed: object;
binary: Uint8Array;
extension: string;
size: number;
}
interface CompressionService {
/**
* 压缩图片并编码
* @param input 原始图片buffer
* @param quality 压缩比
* @param width 压缩的宽度
* @param height 压缩的高度
*/
compImg(input: Buffer, quality: number, width?: number, height?: number): Promise<EncodeResult>
}
class CompressionServiceImpl implements CompressionService {
/**
* 接受压缩图像的管道,如果关闭,将无法再调用 ingestImage 传递图像
*/
private imagePool = new ImagePool(cpus().length);
// private imagePool = new ImagePool(1);
async compImg(input: Buffer, quality: number, width?: number, height?: number): Promise<EncodeResult> {
let image = this.imagePool.ingestImage(input.buffer);
let preprocessOptions = {}
if (width != null && height != null) {
preprocessOptions = {
resize: {
width: width,
height: height,
}
}
}
await image.preprocess(preprocessOptions);
await image.encode({
mozjpeg: {
quality: quality
}
})
return image.encodedWith.mozjpeg
}
}
export const compressionService = new CompressionServiceImpl()
-
使用
if (quality == null) quality = this.quality
console.log("压缩前的图片大小:", imgBuffer.length / 1024, "kb")
//将图片编码压缩
let promise = await compressionService.compImg(imgBuffer, quality, width, height)
//这里必须用Buffer.from转换一下,不然后面转base64后显示是乱的
let buffer = Buffer.from(promise.binary.buffer)
console.log("压缩后的图片大小:", buffer.length / 1024, "kb")
let extension = promise.extension
// 输出到磁盘
// this.testFile(extension, buffer)
//最终得到的内容 buffer, quality, extension, width, height
-
quality
参数必须设置,1
到100
的整数,我的默认值是75
,这个值在整个压缩过程影响非常重要。 -
只有 quality
设置到小于等于10
时,图片才会模糊的影响观看; -
压缩时设置 width
和height
会导致压缩时间变长,相同quality
下画质会更差。
四、性能测试
为了方便得出quality
设置为多少合适,我做了个测试。硬件环境:CPU:2.8GHz 四核 Intel Core i7 、RAM:16GB 2133MHz
测试流程:用一张800
kb左右的图片输入,分别设置quality
值为10、20... 90
,每次压缩100
次,根据耗时和压缩次数计算平均值
结算 >>>> quality: 10 平均耗时 ms: 1189.48 buffer长度: 62.1396484375 kb
结算 >>>> quality: 20 平均耗时 ms: 1201.16 buffer长度: 97.7294921875 kb
结算 >>>> quality: 30 平均耗时 ms: 1389.94 buffer长度: 122.353515625 kb
结算 >>>> quality: 40 平均耗时 ms: 1360.13 buffer长度: 147.0166015625 kb
结算 >>>> quality: 50 平均耗时 ms: 1393.16 buffer长度: 169.2646484375 kb
结算 >>>> quality: 60 平均耗时 ms: 1451.79 buffer长度: 193.9453125 kb
结算 >>>> quality: 70 平均耗时 ms: 1512.31 buffer长度: 227.6171875 kb
结算 >>>> quality: 80 平均耗时 ms: 1893.59 buffer长度: 301.37890625 kb
结算 >>>> quality: 90 平均耗时 ms: 2866.18 buffer长度: 480.5 kb
对图片要求不高,设置quality
为20
差不多了
参考资料
squoosh: https://squoosh.app/
[2]squoosh index.ts: https://github.com/GoogleChromeLabs/squoosh/blob/dev/libsquoosh/src/index.ts
文章评论