大家在日常工作中肯定会遇到需要上传图片到后端的情况,但是呢,图片如果太大,而我们并不需要高清的图片的时候,就需要对图片进行压缩在上传,就会大大提高效率。
实现方法
监听input file的onchange事件,用FileReader 读取用户使用input file上传的图片
public url: string;
loadImg(file) {
const reader = new FileReader();
reader.onload = (e: any) => {
this.url = e.target.result;
};
reader.readAsDataURL(file);
}
把图片数据传入img对象,然后将img绘制到canvas上,再调用canvas.toDataURL对图片进行压缩,获取到压缩后的base64格式图片数据,转成二进制
// quality:默认压缩品质0.7, wh:传入函数的图片压缩后的最大图片宽度和高度,默认是1000,单位是px
processImg(quality = 0.7, wh = 1000) {
if (!this.url) {
return;
}
const img = new Image();
img.src = this.url;
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
let height = img.height;
let width = img.width;
let imgWH = 1000;
if (wh && wh < 1000 && wh > 0) {
imgWH = wh;
}
// 按比例缩小图片
if (width > imgWH || height > imgWH) {
const ratio = Math.floor((height / width * 10)) / 10;
if (width > height) {
width = imgWH;
height = imgWH * ratio;
} else {
height = imgWH;
width = height / ratio;
}
img.width = width;
img.height = height;
}
canvas.width = width;
canvas.height = height;
ctx.fillStyle = '#fff';
ctx.fillRect(0, 0, width, height);
ctx.drawImage(img, 0, 0, width, height);
return canvas.toDataURL('image/jpeg', quality);
}
获取到压缩后的图片二进制数据,转换成File对象传给后端
convertBase64toFile(base64) {
const date = new Date().valueOf();
const imageName = date + '.jpg';
const imageBlob = this.dataURItoBlob(base64);
const imageFile = new File([imageBlob], imageName, { type: 'image/jpg' });
return imageFile;
}
dataURItoBlob(dataURI) {
const byteString = atob(dataURI.split(',')[1]);
const mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
console.log(mimeString);
const arrayBuffer = new ArrayBuffer(byteString.length);
const int8Array = new Uint8Array(arrayBuffer);
for (let i = 0; i < byteString.length; i++) {
int8Array[i] = byteString.charCodeAt(i);
}
const blob = new Blob([int8Array], { type: 'image/jpg' });
return blob;
}
// angular httpClient
uploadFile(file){
var formData = new FormData();
formData.append("files", file);
this.httpClient.post(FileUploadUrl, formData)
}
//上传图片
const fileForUpload = this.convertBase64toFile(this.processImg());
this.uploadFile(fileForUpload);
这样就完成了图片的压缩,上传,也可以预览。