在做移动端图片上传的时候,用户传的都是手机本地图片,而本地图片一般都相对比较大,拿iphone6来说,平时拍很多图片都是一两M的,如果直接这样上传,那图片就太大了,如果用户用的是移动流量,完全把图片上传显然不是一个好办法。
在移动端压缩图片并且上传主要用到filereader、canvas 以及 formdata 这三个h5的api。逻辑并不难。整个过程就是:
(1)用户使用input file上传图片的时候,用filereader读取用户上传的图片数据(base64格式)
(2)把图片数据传入img对象,然后将img绘制到canvas上,再调用canvas.toDataURL对图片进行压缩
(3)获取到压缩后的base64格式图片数据,转成二进制塞入formdata,再通过XmlHttpRequest提交formdata。
<input
v-show="!imgSrc && !imgload"
type="file"
accept="image/png,image/gif,image/jpeg"
class="upload-input"
@change="uploadFunc"
/>
compressImage(file) {
// 参数file,是通过input 选择本地文件获取的
return new Promise((resolve) => {
const { type, name } = file;
let img = new Image();
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function(e) {
// 文件加载成功后去转成Img对象,为了拿到图片的原始宽高
img.src = e.target.result;
img.onload = function() {
// 创建画布canvas
let canvas = document.createElement('canvas');
let content = canvas.getContext('2d');
// 设置画布的宽高
canvas.width = img.width; // 需要压缩到的图片宽度
canvas.height = img.width * (img.height / img.width);
// 将图片画在画布上
content.drawImage(img, 0, 0, canvas.width, canvas.height);
//画布转成blob格式的图片
canvas.toBlob(function(blob) {
// blob 格式的图片 转成file对象,这里主要看接口支不支持blob格式的文件上传,如果支持就没有必要转
let file = new File([blob], name, { type: type });
resolve({type: type, compressFile: file})
}, `image/${type.split('/')[1]}`, 0.7); // 0.7 是文件压缩程度
}
}
});
},
uploadFunc(e) {
let file = e.target.files[0];
if (file.size) {
const isLt2M = file.size / 1000 / 1000 < 15;
if (!isLt2M) {
Toast('上传图片大小不能超过 15MB!');
return;
}
}
let minImage = this.compressImage(file);
minImage.then(result => {
console.log('imgtype----' + result.type);
this.file = result.compressFile;
this.imgload = true;
let param = new FormData();
param.append('file', result.compressFile);
let config = {
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
};
axios.post('/duihuan/order/ajax_upload_img', param, config).then(res => {
if(res.data.error_code === 0) {
this.imgSrc = res.data.data.url;
} else {
Toast(res.data.error_msg);
}
this.imgload = false;
});
});
},
使用压缩后,上传一个5.4兆的图片,发现压缩后的上传的图片大小是1.1兆(1066753/1024/1024),接口请求时间也由原先的六七秒降为两秒多