前端时间写过一篇通过循环判断是否符合最低要求的压缩图片方式,但是整体时间长,特大图压缩后图片清晰度也不太高,因此又总结了一下通过直接设置最小边距(宽/高),然后降低图片质量,压缩时间短清晰度也可以,整体逻辑和其他几章大同小异
canvas压缩多张图片(一)
canvas压缩多张图片(三)
input 上传图片
<input
type="file"
accept="image/*"
@change="onFileChange('photoID')"
ref="photoID"
name="file1"
class="btn"
:multiple="!!multiple"
/>
获取到文件,进行压缩
async onFileChange(name) {
// 通过DOM取文件数据
let inputDOM = this.$refs[name];
//是否多选
if(!!this.multiple){
let arr =[];
let files = inputDOM.files;
for(let i=0;i<files.length;i++){
let imageUrl = await getCreateObjectURL(files[i]);
let src = await convertImgToBase64({url:imageUrl,type:files[i].type},files[i]);
arr.push(src);
console.log(arr,'压缩后base64数组')
}
this.$emit('onFileChange',arr,primaryArr);
} else{
let file = inputDOM.files[0];
let imageUrl =await getCreateObjectURL(file);
let src = await convertImgToBase64({url:imageUrl,type:file.type},file);
console.log(src,'压缩后base64')
}
loadingInstance.close();
//重置value
inputDOM.value = '';
}
压缩核心
//canvas 压缩
convertImgToBase64 =(obj,file,stopAsync) =>{
let Num= 1024 *0.2;
obj.num = obj.num || 1;
//是否重复压缩
stopAsync = !!stopAsync;
//如果是微信图片 转 jpeg
if(obj.type =='image/webp'){
obj.type ='image/jpeg';
}
return new Promise(async (resolve)=>{
if(obj.type =='image/gif'){
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function (e) {
resolve(e.target.result)
}
return
}
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
var img = new Image;
img.crossOrigin = 'Anonymous';
img.src = obj.oldUrl || obj.url;
img.onload = async()=>{
var imgW = img.width;
var imgH = img.height;
var cvsw,cvsh;
//横向 图
if(imgW > imgH){
cvsh = imgH > 1334 ? 1334 : imgH;
cvsw = cvsh / imgH * imgW
} else if(imgW < imgH){//纵向图
cvsw = imgW > 750 ? 750 : imgW;
cvsh = cvsw / imgW * imgH
} else if(imgW == imgH && imgW > 750){//正方形
cvsw = 750;
cvsh = 750;
} else {
cvsw = imgW;
cvsh = imgH;
}
canvas.width = cvsw;
canvas.height = cvsh;
ctx.drawImage(img,0,0,cvsw,cvsh);
let dataURL ='';
if(stopAsync){
dataURL = canvas.toDataURL(obj.type,obj.num);
ctx.fillStyle = "#fff";
ctx.fillRect(0, 0, canvas.width, canvas.height);
} else {
dataURL = canvas.toDataURL(obj.type);
}
let imgSize = getBase64Size(dataURL);
if( imgSize >= Num && obj.num >0.4){
console.log('去压缩')
obj.num = obj.num - 0.2 ;
obj.num = obj.num.toFixed(2) *1
obj.type = 'image/jpeg';
canvas = null;
await convertImgToBase64({url:dataURL,num :obj.num,type:obj.type,oldUrl:obj.url},file,true).then((res)=>{
resolve(res)
});
} else{
canvas = null;
resolve(dataURL)
}
};
})
},
//将base64 判断大小
getBase64Size =(base64url) =>{
//获取base64图片大小,返回KB数字
var strLength =base64url.length;
var fileLength = parseInt(strLength - (strLength / 8) * 2);
// 由字节转换为KB
var size = "";
size = (fileLength / 1024).toFixed(2);
return parseInt(size) *1;
},
//获取路径
getCreateObjectURL =(file) =>{
var url = null ;
if (window.createObjectURL!=undefined) { // basic
url = window.createObjectURL(file) ;
} else if (window.URL!=undefined) { // mozilla(firefox)
url = window.URL.createObjectURL(file) ;
} else if (window.webkitURL!=undefined) { // web_kit or chrome
url = window.webkitURL.createObjectURL(file) ;
}
return url ;
}