h5页面利用canvas压缩图片并上传

时间:2022-05-23 19:43:30

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