前俩天做了
一个图片转base64
上传的
功能,发现如果
图片的base64过大的话,请求会变的很慢,严重的直接超时了,所以想到了在
上传前压缩一下
图片,然后再
上传到
后台,这样可以大大的提高效率,
在这里记录一下利用 canvas 压缩
图片遇到的几个坑。完整
代码会在文末给出。
第
一个坑,在压缩
图片的时候没
获取图片本身的宽高,给了
一个 600*480 的定宽定高,因为是手机端的,在
上传图片的时候都是几兆的
图片,所以这块没任何问题。出问题的地方在
修改头像的时候,测试的时候
上传的
图片都是小
图片,然后就出现了 压缩后的
图片显示不完全,大部分都是空白的现象,这就是因为在压缩的时候没有考虑
图片原本的宽高的情况。
第二个坑,
解决第
一个坑的办法就是在
图片加载完成后(onload),
获取图片本身的宽高,然后赋值给 canvas,这样进行操作,但是这有个坑就是,
图片加载是异步的,在你 return 的时候,返回的可能是 undefined 而不是你需要的 压缩后的 base64。这里的
解决方法是,新建
一个 Promise ,然后把结果 resolve() 返回去,在
调用的时候 .then() 得到结果。
知识点:
canvas 的 toDataURL('image/png',0.9) ; 把 canvas 画的
图片转换为 base64,第
一个参数表示的是
图片的类型,第二个参数表示的是
图片的清晰度。
规定
一个最大尺寸,如果
图片本身的宽高大于这个尺寸,按照最大的
一个边进行缩放,另
一个根据
图片的 比例 进行设置,然后设置给 canvas .
miniImage.js
export default async function miniSize(imgData,maxSize = 200*1024){
// const maxSize = 200 * 1024;
if(imgData && imgData.files && imgData.files.size < maxSize) {
return imgData.url;
}else{
console.log('----------------压缩图片-------------------');
const canvas = document.createElement('canvas');
let img = new Image();
img.src = imgData.url;
let ctx = canvas.getContext('2d');
return new Promise((resolve =>{
img.addEventListener('load',function(){
//
图片原始尺寸
let originWidth = this.width;
let originHeight = this.height;
// 最大尺寸限制
let maxWidth = 400,maxHeight = 400;
// 目标尺寸
let targetWidth = originWidth,targetHeight = originHeight;
//
图片尺寸超过400x400的限制
if (originWidth > maxWidth || originHeight > maxHeight) {
if (originWidth / originHeight > maxWidth / maxHeight) {
// 更宽,按照宽度限定尺寸
targetWidth = maxWidth;
targetHeight = Math.round(maxWidth * (originHeight / originWidth));
} else {
targetHeight = maxHeight;
targetWidth = Math.round(maxHeight * (originWidth / originHeight));
}
}
canvas.width = targetWidth;
canvas.height = targetHeight;
ctx.drawImage(img,targetWidth,targetHeight);
let base64 = canvas.toDataURL('image/png',0.9);
resolve(base64);
},false);
}))
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。