前端图片压缩三方库browser-image-compression的使用实践

20251106再次实测补充:使用过程中发现browser-image-compression的压缩耗时较长,达到compressorjs的5倍,开始以为是开了WebWorker,但是关了以后耗时没有任何改善,鉴于一次压缩图片数量不多(最多8张,大多数时候只有一两张),不需要后台执行,另外也没有压缩png图片的需求,所以改换compressorjs,这样一张8M左右的手机照片,压缩时间能从2.2秒降低到0.4秒,可谓提速非常明显了,另外设置参数convertSize: 1000000, 1MB以上的png转换为JPEG.

------------------------------------------------------------------------

再次实测补充:browser-image-compression是三个库中唯一可以真正压缩PNG图片的,压缩率取决于图片内容,比如透明较多的图片,压缩率较高;compressorjs对png几乎无法压缩,但可以配置当PNG图片大小大于多少转成JPG进行压缩(browser-image-compression没有这个配置参数,但这种逻辑简单,可以自己写),然后他的方法不是promise用起来不太方便;第三个image-conversion有点自欺欺人了,PNG放进去是转jpg压缩后又转回png,结果就是透明的部分不透明了;

------------------------------------------------------------------------

上篇文章是deepseek给出的前端图片压缩方案建议,后经过查看各第三方库的github项目和压缩后相同大小文件的对比,可以得出结论,这几个三方库其实也都是浏览器原生Canvas API的封装.当然,不管它们怎么实现的,只要用起来方便好用就行了,其中browser-image-compression支持WebWorker,压缩大图片时不易阻塞界面交互, image-conversion特色是压缩到指定大小,我的需求还是保证肉眼看不出明细区别为前提,尽量压缩,所以固定一个大小并不是我的需求,测试过大小设置太小则大图片失真严重,设置过大则小图片基本没压缩,最终还是使用前者,前者一个主意事项是,压缩后返回的是blob,如果原来上传方法要传file,则要转换一下,方法和其他注意事项见代码:

 1 // 循环对图片进行上传,如果有上传失败的进行提示
 2       // console.log("=====上传前图片==", fileList.value)
 3       for (const item of fileList.value) {
 4 
 5         if (item.status === 'done') {
 6           continue
 7         }
 8         const sourceFile = item.file;
 9         if (sourceFile) {
10 
11           let upFile = null
12           //如果是图片
13           if (sourceFile.type && sourceFile.type.startsWith('image/')) {
14             // 对图片进行压缩
15             const options = {
16               maxSizeMB: 0.5, // 最大文件大小(MB)(作用不大,主要看质量和分辨率)
17               // maxWidthOrHeight: 8000, // 最大宽或高
18               useWebWorker: true, // 使用WebWorker,避免阻塞界面
19               initialQuality: 0.6, // 初始压缩质量(0-1)(经测试0.6及以上肉眼看区别不明显,以下会出现偏色色块)
20               alwaysKeepResolution: true,//保持高宽(即保持分辨率,对有文字的图片,能最大程度保证文字可读)
21             };
22             try {
23               const compressedFile = await imageCompression(sourceFile, options);
24               // console.log('压缩成功,压缩后大小===', compressedFile.size/1024 +'K');
25               // 压缩后是blob需要转换回file
26               upFile = new File([compressedFile], compressedFile.name, { type: compressedFile.type });
27             } catch (error) {
28               console.error('压缩失败:', error);
29             }
30           }
31           if(upFile == null) {
32             upFile = sourceFile;
33           }
34           const formData = new FormData();
35 
36           formData.append('file', upFile);
37           formData.append('checkId', resData.id);
38           formData.append('upType', '1');// 类型:问题照片
39 
40           const uploadRes = await AxiosPost( VITE_APP_API_CHECKS+'/api/checks/checks/uploadImg', formData)
41           // 如果失败,进行提示
42           if(!uploadRes.success){
43             showFailToast('上传失败!'+uploadRes.msg)
44             return
45           }
46 
47           // console.log('===========uploadRes:', uploadRes)
48         }
49       }

 

posted @ 2025-11-05 14:55  dirgo  阅读(31)  评论(0)    收藏  举报