现在一般手机拍的照片都有几M,图片太多不仅占用空间大,而且也会影响上传速度,故上传图片前进行压缩就很有必要了。
解决思路
利用canvas进行图片压缩,canvas的toDataURL方法的第二个参数是图片质量,通过取不同的图片质量来达到压缩的效果。
解决步骤
1、获取到图片的base64格式。
2、等到图片加载完成后,将图片画到canvas上。
3、利用canvas的toDataURL方法来实现压缩。
4、将dataURL转换成Bolb对象。
5、将Bold对象转换成formData对象。
6、通过ajax发送给后台。
html
<input type="file" id="file" />
图片压缩
(1)需要在图片加载完毕后才进行压缩
mainEvent:function(){
let that=this; // 将vue的上下文this挂在that上,避免与reader.onload()方法的回调函数中的this冲突
let file=document.getElementById('file').files[0];
let reader=new FileReader();
reader.readAsDataURL(file);
reader.onload=function () {
let content=this.result; //图片的src,base64格式
let img = new Image();
img.src=content;
img.onload=function (){ //图片加载完毕
that.compressEvent(img,(dataURL)=> {
that.uploadImg(dataURL,file);
})
}
};
},
(2)把图片绘制到canvas上去
compressEvent:function(img,callback){
let that=this;
let canvas=document.getElementById('myCanvas');
let ctx=canvas.getContext('2d');
let initSize=img.src.length;
let width=img.width;
let height=img.height;
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
let dataURL = canvas.toDataURL("image/jpeg", 0.1);
callback?callback(dataURL):null; //调用回调函数
}
图片上传
(3)dataURL转换为Bold对象或File对象
File继承于Blob,扩展了一些属性(文件名、修改时间、路径等)。绝大多数场景下,使用Bolb对象就可以了。兼容性:Edge浏览器不支持File对象构造函数,也就是Edge里不能new File()。 这里以dataURL转Bold对象为例。
dataURItoBlob(dataurl){ //dataurl是base64格式
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], {type:mime});
},
(4)将Bold对象转换成formData对象,并提交
uploadImg:function (dataURL,file){
let blob=that.dataURItoBlob(dataURL);
let formData = new FormData();
formData.append("file",blob,file.name);
const instance=axios.create({ withCredentials: true})
let config = { headers: { "Content-Type": "multipart/form-data" }};
instance.post('/api/msgreply/UploadImg',that.formData,config).then(res => {
//success
}).catch(err => {
//fail
});
}