我们常常在选择完图片后需要对图片进行处理,包括格式转换以及压缩等,最近遇到此场景,故整理汇总为如下:
// 图片处理, 输入文件,输出base64和文件
dealImg(file: File, callback: any) {
this.fileToBase64(file, (base64: any) => {
this.compressImg(base64, (compressBase64: any) => {
callback({
base64,
file: this.base64ToFile(compressBase64, file.name)
});
});
});
}
// 获取图片用于展示,输入文件,输出base64
fileToBase64(file: File, callback: any) {
const fr = new FileReader();
fr.onload = (evt: any) => {
callback(evt.target.result);
};
fr.readAsDataURL(file);
}
// 图片压缩,输入base64,输出base64
compressImg(base64: any, callback: any, w: number = 1000) {
const newImage = new Image();
const quality = 0.8; // 压缩系数0-1之间
newImage.src = base64;
newImage.setAttribute("crossOrigin", 'Anonymous'); // url为外域时需要
let imgWidth;
let imgHeight;
newImage.onload = function() {
// @ts-ignore
imgWidth = this.width;
// @ts-ignore
imgHeight = this.height;
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d") as any;
if (Math.max(imgWidth, imgHeight) > w) {
if (imgWidth > imgHeight) {
canvas.width = w;
canvas.height = w * imgHeight / imgWidth;
} else {
canvas.height = w;
canvas.width = w * imgWidth / imgHeight;
}
} else {
canvas.width = imgWidth;
canvas.height = imgHeight;
}
ctx.clearRect(0, 0, canvas.width, canvas.height);
// @ts-ignore
ctx.drawImage(this, 0, 0, canvas.width, canvas.height);
const newBase64 = canvas.toDataURL("image/jpeg", quality);
callback(newBase64); // 必须通过回调函数返回,否则无法及时拿到该值
}
}
// 将base64转换为文件格式
base64ToFile(base64: string, fileName: string): File {
const arr = base64.split(',');
// @ts-ignore
const mime = arr[0].match(/:(.*?);/)[1];
const bytes = atob(arr[1]);
const bytesLength = bytes.length;
const u8arr = new Uint8Array(bytesLength);
for (let i = 0; i < bytes.length; i++) {
u8arr[i] = bytes.charCodeAt(i);
}
const blob = new Blob([u8arr], { type: mime })
return new File([blob], fileName, {
type: 'image/jpeg'
});
}
调用方式如下:
// 单个文件处理,如果有有多文件可以遍历处理
onSingleFileChange(e: any) {
const files = e.target.files;
this.dealImg(files[0], (result: any) => {
console.log(result);
});
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。