大致思路:
1.将拿到的file文件对象转换成Img元素标签(FileReader)
2.获取该元素标签的宽高,计算需要压缩的尺寸,创建canvas实例,将该元素标签绘制到canvas上
3.通过canvas的tuDataRUL方法返回压缩后图片的base6编码,可根据自己的需求转换成file或者blob
//将DataURL转成file
const dataURLToFile=(dataUrl,fileName)=>{
const dataArr = dataUrl.split(',')
const mime = dataArr[0].match(/:(.*);/)[1]
const originStr = atob(dataArr[1])
let n = originStr.length
const u8Arr = new Uint8Array(n)
while (n--) {
u8Arr[n] = originStr.charCodeAt(n)
}
return new File([u8Arr],fileName, { type: mime })
};
//图片压缩
const compressImg=(file)=>{
//file文件
let disposeFile = file;
//如果当前获取到的file为blob对象,将其转换成file对象
if(Object.prototype.toString.call(file)==='[object Blob]'){
disposeFile = new File([file],file.name,{type:file.type});
}
//file文件流大小
const fileSize = parseFloat(parseInt(disposeFile['size'])/1024/1024).toFixed(2);
//小于1M不压缩
if(fileSize < 1 )return file;
//FileReader 读取单个对象文件
const reader = new FileReader();
return new Promise((resolve,reject)=>{
try{
//readAsDataURL方法 读取file对象
reader.readAsDataURL(file);
//在读取完成时触发
reader.onload=()=>{
//创建img元素标签
const img = new Image();
console.log(reader.result)
//将FileReader读取的file对象文件(base64编码)赋值给img的src属性完成file对象文件到Img元素标签的转换
img.src = reader.result;
img.onload=()=>{
//获取img图片宽高
const { width: originWidth, height: originHeight } = img
// 设置最大尺寸限制
const maxWidth = 1000;
const maxHeight = 1000;
// 需要压缩的目标尺寸
let targetWidth = originWidth, targetHeight = originHeight
// 等比例计算超过最大限制时缩放后的图片尺寸
if (originWidth > maxWidth || originHeight > maxHeight) {
if (originWidth / originHeight > 1) {
// 宽图片
targetWidth = maxWidth
targetHeight = Math.round(maxWidth * (originHeight / originWidth))
} else {
// 高图片
targetHeight = maxHeight
targetWidth = Math.round(maxHeight * (originWidth / originHeight))
}
}
//创建canvas对象
const canvas = document.createElement("canvas");
// canvas对图片进行裁剪,设置图片压缩完的尺寸
canvas.width = targetWidth;
canvas.height = targetHeight;
const ctx = canvas.getContext("2d");
// canvas中,png转jpg会变黑底,所以先给canvas铺一张白底
ctx.fillStyle = "#fff";
// fillRect()方法绘制一个填充了内容的矩形
ctx.fillRect(0,0,canvas.width,canvas.height);
// 绘制图像
ctx.drawImage(img,0,0,targetWidth,targetHeight);
// canvas转图片 实现图片压缩
let base64;
if(fileSize < 1){
//图片小于1M 不执行压缩操作
base64 = canvas.toDataURL(disposeFile['type'],1)
}else if(fileSize > 1 && fileSize < 2){
//图片大于1M但是小于2M 图片压缩0.5
base64 = canvas.toDataURL(disposeFile['type'],0.5);
}else{
//图片大于2M 图片压缩0.2
base64 = canvas.toDataURL(disposeFile['type'],0.2)
}
resolve(dataURLToFile(base64,disposeFile.name))
}
};
}catch (e) {
reject(e);
}
})
}
export { compressImg }