由于现在手机拍摄的照片质量较高,为减轻服务器压力在上传图片时需要压缩后再进行上传。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