一、场景 / 需求
1、使用 antd-mobile 中的 ImagePicker 组件上传
2、onChange 获取到上传图片,当图片大于500kb 时进行图片压缩
二、实现分析
1、onChange事件获取到第一个参数 curFiles: any[], curFiles 包含 file、url 两部分
2、file 中可以获取文件大小判断是否压缩,url 获取图片信息,进行压缩
三、具体实现
new File 可以将生成的 blod 数据转为 file 格式
// 将图片转为二进制
dataURLtoBlob = (dataurl: any) => {
const arr = dataurl.split(',')
const mime = arr[0].match(/:(.*?);/)[1]
const bstr = atob(arr[1])
let n = bstr.length
const u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], {
type: mime,
})
}
// 图片压缩
compressImg = (imgInfo: any, outputFormat?: any) => {
const that = this
return new Promise((resolve) => {
if (imgInfo.file.size <= 5e5){
// 小于500kb(500,000) 不压缩
resolve(imgInfo.file)
} else {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d') || null;
const img = new Image;
img.src = imgInfo.url;
img.crossOrigin = 'Anonymous';
img.onload = function () {
const width = img.width;
const height = img.height;
// 比例可根据项目需要自行修改
const rate = 1 / (Math.round(width / 750) || 1);
canvas.width = width * rate;
canvas.height = height * rate;
ctx && ctx.drawImage(img, 0, 0, width, height, 0, 0, width * rate, height * rate);
const dataURL = canvas.toDataURL(outputFormat || 'image/jpeg', 0.9); // 0.9 可改成0-1,清晰度
resolve(new File(
[that.dataURLtoBlob(dataURL)],
imgInfo.file.name
))
}
}
})
}
// 图片数据发生变化时
handleUploadChange = (curFiles: any[], type: string, index: Number) => {
if (type === 'add') {
this.compressImg(curFiles[curFiles.length - 1]).then((res: any) => {
const uploadParams = {
file: res
...
}
}
}else if (type = 'remove') {
... ...
}
})