HTML5 Canvas上传自动压缩图片

场景描述

上次好不容易搞清楚,前端使用base64编码格式上传图片,但随之而来又有了新问题,那就是

图片大小怎么控制?

  • 让用户自己压缩?这不科学
  • 直接丢给后端处理?貌似也可以
  • 前端压缩完后直接给后端处理?那最好不过了

跑去问前端,JavaScript可以直接压缩后上传吗?前端答曰:不行。碰一鼻子灰,那就只能丢给后端PHP去做裁剪了。
假设用户拍了一张5M左右的图,然后直接上传,信号不好的时候,速度还是很慢的,不过这不是重点,重点是TM流量贵啊~要是失败一次,再重来,那分分钟10几M流量就没了,用户那得哭,这个可不行,这事还是得前端做。
网上Google一下,立马一大堆解决方案,内心瞬间…你懂的~

实践

Google搜索了一下结果,先讲思路,申明一个new Image()canvas对象,然后通过canvas裁剪大小,把结果赋给Image对象。理解思路没错,但是不如直接使用成熟的库。介绍一下在Github上的一个好用的类库:localResizeIMG 。Star数有1500+,已经很好了,文档也详细,虽然不再更新了,但只要好用就好了。
代码实现如下:

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
32
33
34
35
36
37
38
39
40
//图片显示
function imgPreview(fileDom) {
//判断是否支持FileReader
if (window.FileReader) {
var reader = new FileReader();
} else {
layer.alert("您的设备不支持图片预览功能,如需该功能请升级您的设备!");
}
//获取文件
var file = fileDom.files[0];
var imageType = /^image\//;
//是否是图片
if (!imageType.test(file.type)) {
layer.alert("请选择图片!");
return;
}
/* 压缩图片 */
lrz(file, {
width: 1200 //设置压缩参数
}).then(function (rst) {
var img = new Image(),
sourceSize = toFixed2(file.size / 1024),
resultSize = toFixed2(rst.fileLen / 1024),
scale = parseInt(100 - (resultSize / sourceSize * 100));
//读取完成
reader.onload = function (e) {
//获取图片dom
var img = document.getElementById("imgPreview");
img.src = rst.base64;
$('#base64').val(rst.base64);
};
reader.readAsDataURL(file);
});
}
function toFixed2 (num) {
return parseFloat(+num.toFixed(2));
}

  • 原图大小4.2M,裁剪之后只有150k左右
坚持原创技术分享,您的支持将是鼓励我继续创作的动力!