Exif.js+Canvas实现移动端图片压缩、旋转、上传预览功能小结

2019-08-01578次阅读javascript

移动端图片上传的时候,都是手机本地图片,而本地图片一般都是1、2M左右,所以有必要按一定的比例压缩后上传。

 

图片压缩

1、input file上传图片的时候,用filereader读取用户上传的图片数据(base64格式)

2、把图片数据传入img对象,然后将img绘制到canvas上,再调用canvas.toDataURL对图片进行压缩。toDataURL()方法返回一个包含图片展示的 data URI ,使用两个参数,第一个参数为图片格式,默认为 image/png。第二个参数为压缩质量,在指定图片格式为 image/jpeg或 image/webp的情况下,可以从0到1的区间内选择图片的质量。

3、获取到压缩后的base64格式图片数据Ajax上传,或者是转成二进制塞入formdata,再通过Ajax提交formdata。

 

图片旋转

移动端上传拍照图片后,会发现有些图片的方向不对,这些是因为拍摄方向不同造成的。解决这个问题的思路是利用Exif.js获取到照片拍摄的方向,然后利用canvas.rotate对照片进行角度旋转修正。

 

Exif.js

Exif.js提供了JavaScript读取图像的原始数据的功能扩展,例如:拍摄方向、相机设备型号、拍摄时间、ISO 感光度、GPS 地理位置等数据。

注:EXIF数据主要来自拍摄的照片,多用于移动端开发,PC 端也会用到,此插件兼容主流浏览器,IE10以下不支持。

 

使用方法

载入JavaScript文件

<script src="exif.js"></script>

获取EXIF数据

<script>
EXIF.getData(document.getElementById('imgElement'), function(){//获取图像的数据,能兼容尚未支持提供 EXIF 数据的浏览器获取到元数据。
  EXIF.getAllTags(this);//获取图像的全部数据,值以对象的方式返回
  EXIF.getTag(this, 'Orientation');//Orientation获取图像的拍摄方向
});
</script>

详细请至中文文档查看:http://code.ciaoca.com/javascript/exif-js/

获取拍摄方向会用到Orientation属性,说明如下:

旋转角度参数值
1
顺时针90°6
逆时针90°8
180°3
 

我试了一下,反方向旋转的横拍是0°(1),正常的竖拍是顺时针90°(6),正方向旋转的横拍是180°(3)。

因篇幅有限,Ajax上传过程略过,只做了如下的简单DEMO,仅供参考:

<div class="wrap">
  <span class="select_file"></span>
  <input type="file" class="file_wrap" accept="image/jpeg,image/jpg,image/png">
  <p>
    <img id="previewImg" src="images/loading.gif">
  </p>
</div>
<script src="script/exif.js"></script>
  <script>
    {
      var doc = document,

        button = doc.querySelector('.select_file'),

        input  = doc.querySelector('.file_wrap'),

        previewImg = doc.querySelector('#previewImg'),

        Orientation = 1,//拍摄方向默认为1显示正常

        upDateFile = ()=>{

          var file = input.files[0];

          if(!file) return;

          var reader = new FileReader();

                    reader.onload = e=>{ 
                            
                    var image = new Image();

                      image.src = e.target.result;

                        image.onload = function(){

                                EXIF.getData(file, function() {

                                    EXIF.getAllTags(this);

                                    Orientation = EXIF.getTag(this, 'Orientation');

                                    //console.log(Orientation);

                                    var imgWidth = image.width,

                                        imgHeight = image.height;
                                        
                                    if(imgWidth > imgHeight && imgWidth > 750){

                                        imgWidth = 750;

                                        imgHeight = Math.ceil(750 * image.height / image.width);

                                    }else if(imgWidth < imgHeight && imgHeight > 1334){

                                        imgWidth = Math.ceil(1334 * image.width / image.height);

                                        imgHeight = 1334;

                                    }
                                    
                                    var canvas = document.createElement("canvas"),

                                        ctx = canvas.getContext('2d');

                                    canvas.width = imgWidth;

                                    canvas.height = imgHeight;

                                    if(Orientation && Orientation != 1){

                                        switch(Orientation){

                                            case 6:

                                                canvas.width = imgHeight;

                                                canvas.height = imgWidth; 

                                                ctx.rotate(Math.PI / 2);

                                                ctx.drawImage(image, 0, -imgHeight, imgWidth, imgHeight);

                                                break;

                                            case 3:

                                                ctx.rotate(Math.PI);

                                                ctx.drawImage(image, -imgWidth, -imgHeight, imgWidth, imgHeight);

                                                break;

                                            case 8:

                                                canvas.width = imgHeight;

                                                canvas.height = imgWidth;

                                                ctx.rotate(3 * Math.PI / 2);

                                                ctx.drawImage(image, -imgWidth, 0, imgWidth, imgHeight);

                                                break;
                                        }

                                    }else{

                                        ctx.drawImage(image, 0, 0, imgWidth, imgHeight);

                                    }

                                   

                                    previewImg.src = canvas.toDataURL("image/jpeg",.8);


                                });

                
                        }

                              

                    };

                    reader.readAsDataURL(file);

        };

      button.addEventListener('click',function(event){

        doc.querySelector('.file_wrap').click();

      },false);

      input.addEventListener('change',upDateFile,false);


    }
  </script>

重点、重点、重点:EXIF.getData必须等待图像完全加载后才可以使用。

上一篇: 没有jquery!原生js可定制的跨浏览器日期时间选择器插件Rome  下一篇: 浅说JavaScript的事件循环面试题  

Exif.js+Canvas实现移动端图片压缩、旋转、上传预览功能小结相关文章