图片压缩上传

之前在做项目的时候经常遇到上传图片的问题,对于太大的图片,如果总时原图上传的话,速度很慢,同时也对服务器造成了较大压力。所以,若非要求原图上传,最好对图片进行一下压缩。

压缩图片我用的是第三方的工具库canvas-resize。其基本思路就是将原图片读取到内存,然后利用canvas画布重新画出来一个压缩后的图片。

用法

1
2
npm install
npm run build
  • 支持AMD, CMD模块化的引入方式
  • 也可通过外链
1
2
3
4
5
6
7
8
canvasResize(this.files[0], {
crop: false, // 是否裁剪
quality: 0.9, // 压缩质量 0 - 1
rotate: 0, // 旋转角度
callback(baseStr) { //返回的结果是base64格式的图片
console.log(baseStr.length)
}
})

将canvas裁剪之后的base64转换为blob对象格式的上传文件

这个canvasResize将图片压缩后的格式的base64,然后拿这个base64格式的图片转为blob格式的图片。

编写一个将以base64的图片url数据转换为Blob的工具👇

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Utility.js
export default {
/**
* 将以base64的图片url数据转换为Blob
* @param urlData String 用url方式表示的base64图片数据
* @param type Object { type: "image/png" }
*/
convertBase64UrlToBlob(urlData, type) {
var bytes = window.atob(urlData.split(',')[1]); //去掉url的头,并转换为byte
//处理异常,将ascii码小于0的转换为大于0
var ab = new ArrayBuffer(bytes.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i);
}
return new Blob([ab], type);
}
};

我在sfa-vue项目中曾应用过的例子👇

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
uploadImg() {
// console.log(this.$refs.file.files[0]);
let formData = new FormData();
// 拿到当前上传的图片
let file = this.$refs.file.files[0];
// 对当前上传的图片file,进行压缩后,callback返回一个base64的字符串
canvasResize(file, {
crop: false, // 裁剪参数
quality: 0.7, // 压缩率, 0-1
rotate: 0, // 是否旋转
callback: baseStr => {
// 返回的base64字符, 转换成Blob
let fileBlob = Utility.convertBase64UrlToBlob(baseStr, {
type: file.type
});
formData.append("imgF", fileBlob);
service
.uploadImg(formData)
.then(res => {
console.log(res);
this.imgs.push({
checked: false,
url: `${process.env.VUE_APP_BASEURL}${res.data.img}`
});
})
.catch(() => {
console.log("上传失败!");
});
}
});
}

经测试,一张120kb的图片使用压缩之后的图片大小为20kb左右。