- 目前只针对jpg/jpeg格式少部分测试,图片最终是以降低图片质量来限制图片大小,与原图差异较大,如果图片本身是以固定宽高(约150px * 150px)展示时,看不出来差异。
- canvas针对png、gif图片的质量降低,处理后图片大小反而增加。不适用于png、gif格式图片
- canvas转换成url前,需要已加载一张图片(称为原图),因此前后将保留两张图片的加载(了解)
- 代码仅处理了本地图片jpg转换(使用new FileReader()创建本地图片路径并以此加载原图),如果需要处理远程图片,则不需要借助new FileReader()来创建本地图片url,但需要为原图增加属性crossOrigin并赋值Anonymous字符串,且原图在页面中加载,才能使用canvas做图片大小转换
- 从控制台输出来看,应该在是图片大小的2.7倍左右。
<input type="file" name="" id="file"> <img src="" alt="" id="preimg" style="width: 150px; height: 150px;"/> <img src="" alt="" id="img" style="width: 150px; height: 150px;"/>
// 测试后定义降低图片质量的encoderOptions值
// 转换后的大小不能保证准确,尽量在800KB以下了
var formatOptionForJPG = [{
encoderOptions: 0.0625,
// 7.85M -> 532KB
maxSize: 8236315
}, {
encoderOptions: 0.125,
// 6.36M -> 552KB
maxSize: 6674942
}, {
encoderOptions: 0.25,
// 5.09M -> 621KB
maxSize: 5340449
}, {
encoderOptions: 0.5,
// 3.20M -> 536KB
maxSize: 3361652
}, {
encoderOptions: 0.92,
// 1.21M -> 519KB
maxSize: 1270719
}, {
encoderOptions: 0.99,
// 605KB -> 547KB
maxSize: 620450,
}, {
encoderOptions: 1,
// 219KB -> 519KB
maxSize: 225061
}];
// 获取encoderOptions
function getEncoderOptionsVal(size, option) {
var result;
option.reverse().some(e => {
result = e.encoderOptions;
return size <= e.maxSize;
});
return result;
}
// 优化图片
function formatPic(doc, optionVal) {
var imgEle = document.getElementById('img');
var preimgEle = document.getElementById('preimg');
let file = new FileReader();
file.readAsDataURL(doc);
file.onload = () => {
let url = file.result;
preimgEle.src = url;
let ext = url.split(';')[0].replace('data:image/', '');
if (ext === 'jpg' || ext === 'jpeg') {
let img = new Image();
img.src = url;
img.onload = () => {
var canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, img.width, img.height);
url = canvas.toDataURL('image/' + ext, optionVal);
imgEle.src = url;
console.log('url', url);
}
} else if (ext === 'png') {
imgEle.src = url;
console.log('url', url);
}
}
}
// 就绪事件
document.addEventListener('DOMContentLoaded', function () {
var inpEle = document.getElementById('file');
inpEle.addEventListener('change', function () {
var doc = this.files[0];
var option = [].concat(formatOptionForJPG);
if (doc.size > option[0].maxSize) {
alert('图片太大的处理');
} else {
var optionVal = getEncoderOptionsVal(doc.size, option);
formatPic(doc, optionVal);
}
this.value = '';
});
});