美文网首页工作生活
解决部分机型拍照图片旋转问题

解决部分机型拍照图片旋转问题

作者: ThemisHoo | 来源:发表于2019-06-29 17:20 被阅读0次

很久以前就遇到过的问题,每次开始解决都遇到BUG就不愿意仔细研究下了,今天总算静下心看看代码。解决了问题还是很开心的!

一、EXIF库的引用和调用

npm install exif-js --save   

Exif.js 是用于从图像文件中读取EXIF元数据的 JavaScript库,该包添加了全局EXIF变量。
EXIF.getData()方法,第一个参数为file文件,第二个参数为回调函数。

import EXIF from 'exif-js'

getExif = () => {
    let img = document.getElementById("img");
    EXIF.getData(img, function() {
        EXIF.getAllTags(this); // 获取图片所有信息
        EXIF.getTag(this, 'Orientation'); // 获取图片方向信息
    });
}

二、判断图片方向

selectFileImage = (e) => {
        let self = this; /*解决后面this指向问题*/
        let file = e.target.files[0]; 
        //图片方向角
        let Orientation = null;  
        if (file) {    
            //获取照片方向角属性,用户旋转控制 
            EXIF.getData(file, function() { 
                EXIF.getAllTags(this);  
                Orientation = EXIF.getTag(this, 'Orientation'); 
                //return; 
            }); 
             
            let oReader = new FileReader(); 
            oReader.onload = function(e) { 
              
                let image = new Image(); 
                image.src = e.target.result; 
                image.onload = function() { /*这里不可以用箭头函数,否则this指向的就不是图片了*/
                /*处理图片宽高大小*/   
                let expectWidth = this.naturalWidth; 
                let expectHeight = this.naturalHeight; 
                if (this.naturalWidth > this.naturalHeight && this.naturalWidth > 800) { 
                    expectWidth = 800; 
                    expectHeight = expectWidth * this.naturalHeight / this.naturalWidth; 
                 } else if (this.naturalHeight > this.naturalWidth && this.naturalHeight > 1200) { 
                    expectHeight = 1200; 
                    expectWidth = expectHeight * this.naturalWidth / this.naturalHeight; 
                 }
                 /*创建canvas画布*/
                 let canvas = document.createElement("canvas") 
                 let ctx = canvas.getContext("2d"); 
                 canvas.width = expectWidth; 
                 canvas.height = expectHeight; 
                 ctx.drawImage(this, 0, 0, expectWidth, expectHeight); 
                  /*开始处理图片旋转问题*/
                  let base64 = null; 
                    // 判断是iOS
                    if (navigator.userAgent.match(/iphone/i)) { 
                        if(Orientation != "" && Orientation != 1){ 
                            switch(Orientation){ 
                                case 6://需要顺时针(向左)90度旋转 
                                    self.rotateImg(this,'left',canvas); 
                                    break; 
                                case 8://需要逆时针(向右)90度旋转 
                                    self.rotateImg(this,'right',canvas); 
                                    break; 
                                case 3://需要180度旋转 
                                    self.rotateImg(this,'right',canvas);//转两次 
                                    self.rotateImg(this,'right',canvas); 
                                    break; 
                            }        
                        } 
                        base64 = canvas.toDataURL("image/jpeg", 0.8); 
                    }else if (navigator.userAgent.match(/Android/i)) {// android 
                        var encoder = new JPEGEncoder(); 
                        base64 = encoder.encode(ctx.getImageData(0, 0, expectWidth, expectHeight), 80); 
                        /*这里实践的时候,在Android上报错,实际上不用判断设备也可以
                           为了以后再研究一下,保留了代码,报错问题先注释掉*/
                    }else{ 
                        if(Orientation != "" && Orientation != 1){ 
                            switch(Orientation){ 
                                case 6://需要顺时针(向左)90度旋转 
                                    self.rotateImg(this,'left',canvas); 
                                    break; 
                                case 8://需要逆时针(向右)90度旋转 
                                    self.rotateImg(this,'right',canvas); 
                                    break; 
                                case 3://需要180度旋转 
                                    self.rotateImg(this,'right',canvas);//转两次 
                                    self.rotateImg(this,'right',canvas); 
                                    break; 
                            }   
                        }     
                        base64 = canvas.toDataURL("image/jpeg", 0.8); 
                    }   
                    /*此刻拿到的base64路径就可以直接赋值给img标签了*/
                };
            }; 
            oReader.readAsDataURL(file); 
        } 
    }

三、实现旋转

rotateImg = (img, direction,canvas) => {           
        //最小与最大旋转方向,图片旋转4次后回到原方向   
        let min_step = 0;   
        let max_step = 3;    
        if (img == null)return;   
        //img的高度和宽度不能在img元素隐藏后获取,否则会出错   
        let height = img.height;   
        let width = img.width;   
        /*这里没看懂 step = 2 是为什么*/
        let step = 2;   
        if (step == null) {   
            step = min_step;   
        }   
        if (direction == 'right') {   
            step++;   
            //旋转到原位置,即超过最大值   
            step > max_step && (step = min_step);   
        } else {   
            step--;   
            step < min_step && (step = max_step);   
        }     
         
        //旋转角度以弧度值为参数   
        let degree = step * 90 * Math.PI / 180;   
        let ctx = canvas.getContext('2d');   
        switch (step) {   
            case 0:   
                canvas.width = width;   
                canvas.height = height;   
                ctx.drawImage(img, 0, 0);   
                break;   
            case 1:   
                canvas.width = height;   
                canvas.height = width;   
                ctx.rotate(degree);   
                ctx.drawImage(img, 0, -height);   
                break;   
            case 2:   
                canvas.width = width;   
                canvas.height = height;   
                ctx.rotate(degree);   
                ctx.drawImage(img, -width, -height);   
                break;   
            case 3:   
                canvas.width = height;   
                canvas.height = width;   
                ctx.rotate(degree);   
                ctx.drawImage(img, -width, 0);   
                break;   
        }   
    }   

以上代码即可解决图片旋转问题,经测试,三星,小米,华为,iPhone等暂时都没问题,其他没有的手机型号欢迎补充~

相关文章

网友评论

    本文标题:解决部分机型拍照图片旋转问题

    本文链接:https://www.haomeiwen.com/subject/pbvpcctx.html