由于现在手机拍摄的照片质量较高,为减轻服务器压力在上传图片时需要压缩后再进行上传。h5页面中压缩图片就需要用canvas来实现,通过固定canvas的宽高重绘图片,来达到压缩的目的。
<div style="margin:0 auto;width:60%;padding-top:80px;">
<input id="file" type="file" accept="image/jpeg,image/png">
<div id="img"></div>
</div>
<script>
var eleFile = document.querySelector('#file');
// 压缩图片需要的一些元素和对象
var reader = new FileReader(), img = new Image();
// 选择的文件对象
var file = null;
eleFile.addEventListener('change', function (event) {
file = event.target.files[0];
// 选择的文件是图片
if (file.type.indexOf("image") == 0) {
reader.readAsDataURL(file);
}else{
alert("不支持的文件格式!");
}
//增加获取照片旋转角度
EXIF.getData(file, function() {
Orientation = EXIF.getTag(this, 'Orientation');
});
});
// 文件base64化,以便获知图片原始尺寸
reader.onload = function(e) {
img.src = e.target.result;
};
// 缩放图片需要的canvas
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
// base64地址图片加载完毕后
img.onload = function () {
// 图片原始尺寸
var originWidth = this.width;
var originHeight = this.height;
// 最大尺寸限制
var maxWidth = 500, maxHeight = 500;
//图片压缩后的宽高(单位像素) // 目标尺寸
var targetWidth = originWidth,
targetHeight = originHeight;
// 图片尺寸超过500x500的限制
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对图片进行缩放
canvas.width = targetWidth;
canvas.height = targetHeight;
// 清除画布
context.clearRect(0, 0, targetWidth, targetHeight);
// 图片展示并旋转
if(Orientation && Orientation != 1){
console.log(Orientation)
switch(Orientation){
case 6:
// 旋转90度
canvas.width = targetHeight;
canvas.height = targetWidth;
context.rotate(Math.PI / 2);
// (0,-imgHeight) 从旋转原理图那里获得的起始点
context.drawImage(this, 0, -targetHeight, targetWidth, targetHeight);
break;
case 3:
// 旋转180度
context.rotate(Math.PI);
context.drawImage(this, -targetWidth, -targetHeight, targetWidth, targetHeight);
break;
case 8:
// 旋转-90度
canvas.width = imgHeight;
canvas.height = imgWidth;
context.rotate(3 * Math.PI / 2);
context.drawImage(this, -targetWidth, 0, targetWidth, targetHeight);
break;
}
}else{
context.drawImage(this, 0, 0, targetWidth, targetHeight);
}
// canvas转为blob并上传
canvas.toBlob(function (blob) {
var newImg = new Image();
newImg.src = URL.createObjectURL(blob);
document.querySelector('#img').appendChild(newImg)
//展示图片
//可直接以blob格式上传到服务器
}, file.type || 'image/png'); };
</script>
最后补充一下,canvas.toBlob()的方法会有兼容问题(移动端目前发现问题的地方是某些手机直接拍照上传的时候)
解决方法:引入了一个blob插件。CDN地址:https://cdn.bootcss.com/javascript-canvas-to-blob/3.14.0/js/canvas-to-blob.js
还有部分手机上的照片上传之后会被默认旋转,使用插件exif.js可以获取照片旋转角度进行纠正,上方代码已补充。CDN地址:https://cdn.bootcss.com/exif-js/2.3.0/exif.js