话不多说直接上代码,这种方式通用,包括在浙里办,h5,web
/**
* @decription 图片压缩
* @parma {Object} file 图片文件对象
* @parma {number} quality 压缩的图片质量0-1
* @return {Promise<File>} 返回文件对象
*/
function compressImage(file, quality = 0.1) {
return new Promise((resolve, reject) => {
let img = new Image();
let reader = new FileReader();
// 读取文件为DataURL
reader.onload = function (e) {
img.src = e.target.result;
};
reader.readAsDataURL(file);
// 图片加载完成后执行
img.onload = () => {
let canvas = document.createElement('canvas');
let ctx = canvas.getContext('2d');
// 计算新的宽度和高度
let width = img.width;
let height = img.height;
// 设置canvas的宽度和高度
canvas.width = width;
canvas.height = height;
// 绘制图片到canvas
ctx.drawImage(img, 0, 0, width, height);
// 将canvas的内容转回dataURL
// let dataUrl = canvas.toDataURL(file.type, quality); // quality范围0到1
canvas.toBlob(
(blob) => {
if (!blob) {
reject(new Error('Failed to create Blob'));
return;
}
// 创建新的File对象
const compressedFile = new File([blob], file.name, {
type: file.type,
});
resolve(compressedFile);
},
file.type,
quality
);
// resolve(dataUrl);
};
img.onerror = reject;
});
},
解释:创建image对象是为了获取图片的宽高。FileReader对象是为了获取图片数据。然后将图片画在canvas上,再输出,我需要返回的数据也是文件对象,具体返回的结果根据自己的需求。 再说一下为什么我要写这篇文章是因为 我发现网上很多方案只通过创建img标签获取图片宽高,这种方式在小程序上应该会存在问题,因为小程序的图标标签和网页的不一样。