实现原理
1、通过canvas进行处理
2、图片宽高等比缩放,当前缩放比例为0.5
3、图片质量压缩,当前质量为0.9
4、得到新的base64位图片,转换为Blob的文件流
具体实现
/**
* * 图片等比压缩
* @param {*} file 原文件流
* @param {*} M 超过几M进行压缩,默认超过1M才进行等比压缩
* @param {*} Fn 回调方法
*/
function compressImg(file,Fn,M=1){
if(file.size>M*1024*1024){
// 压缩图片需要的一些元素和对象
let reader = new FileReader(), img = new Image();
// 选择的文件对象
/* let file = null; */
// 缩放图片需要的canvas
let canvas = document.createElement('canvas');
let context = canvas.getContext('2d');
// base64地址图片加载完毕后
img.onload = function () {//显示原始宽高--originWidth + "*" + originHeight; 显示原始大小(file.size / 1024 / 1024) + "M"
// 图片原始尺寸
let originWidth = this.width;
let originHeight = this.height;
// 缩放比例
let sizes = 0.5;
// 缩放后的尺寸
let maxWidth = originWidth * sizes, maxHeight = originHeight * sizes;
//let maxWidth = 700, maxHeight = Math.round(maxWidth / (originWidth / originHeight));//显示压缩后的大小 maxWidth + "*" + maxHeight
// 目标尺寸
let targetWidth = originWidth, targetHeight = originHeight;
// 判断图片原始尺寸是否超过缩放后的尺寸
if (originWidth > maxWidth || originHeight > maxHeight) {
// 判断缩放后的尺寸是否与原图片的尺寸等比
if (originWidth / originHeight > maxWidth / maxHeight) {
// 更宽,按照宽度限定尺寸
targetWidth = maxWidth;
targetHeight = Math.round(maxWidth * (originHeight / originWidth));
} else {
// 等比
targetHeight = maxHeight;
targetWidth = Math.round(maxHeight * (originWidth / originHeight));
}
}
// canvas对图片进行缩放
canvas.width = targetWidth;
canvas.height = targetHeight;
// 清除画布
context.clearRect(0, 0, targetWidth, targetHeight);
// 图片压缩 ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight); sx(裁剪x轴) , sy(裁剪y轴) , swidth(原始裁剪宽) , sheight(原始裁剪高) //裁剪原图片 dx(x轴), dy(y轴), dWidth(缩放宽), dHeigh(缩放高)//绘图图片位置与缩放
context.drawImage(img, 0, 0, originWidth, originHeight,0, 0, targetWidth, targetHeight);
// 获取图片压缩后的base64文件,0.9的质量
let img_base64 = canvas.toDataURL(file.type,0.9);//type----图片格式,默认为 image/png。encoderOptions----在指定图片格式为 image/jpeg 或 image/webp的情况下,可以从 0 到 1 的区间内选择图片的质量。如果超出取值范围,将会使用默认值 0.92。其他参数会被忽略。
file=base64toFile(img_base64,file.name);
file.base64=img_base64;
Fn(file);//压缩后的文件流
};
reader.onload = function (e) {// 文件base64化,以便获知图片原始尺寸
img.src = e.target.result;
};
reader.readAsDataURL(file);//读取文件
}else{
Fn(file);
}
}
/**
* base64转文件流
* @param {*} base64Data base64位图片
* @param {*} filename 图片名称
* @returns
*/
function base64toFile(base64Data, filename = new Date().getTime()) {
//将base64转换为blob
function dataURLtoBlob(dataurl) {
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 });
};
//将blob转换为file
function blobToFile(theBlob, fileName = new Date().getTime()){
theBlob.lastModifiedDate = new Date();
theBlob.name = fileName;
return theBlob;
};
//调用
return blobToFile(dataURLtoBlob(base64Data),filename)
}