利用exif.js解决ios手机上传竖拍照片旋转90度问题

23 篇文章 0 订阅
16 篇文章 0 订阅

html5+canvas进行移动端手机照片上传时,发现ios手机上传竖拍照片会逆时针旋转90度,横拍照片无此问题;Android手机没这个问题。

因此解决这个问题的思路是:获取到照片拍摄的方向角,对非横拍的ios照片进行角度旋转修正。

利用exif.js读取照片的拍摄信息,详见  http://code.ciaoca.com/javascript/exif-js/

这里主要用到Orientation属性。

Orientation属性说明如下:

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


下面就直接上代码了。

主要有html5页面和一个js,示例功能包含了图片压缩和旋转。

自己写的是uploadImage.js。

html5测试页面如下:

[javascript]  view plain  copy
  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4.     <meta charset="utf-8">  
  5.     <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />  
  6.     <title>图片上传</title>  
  7.     <script type="text/javascript" src="js/jquery-1.8.3.js"></script>  
  8.     <script type="text/javascript" src="js/uploadPicture/uploadImage.js" ></script>  
  9.         <script type="text/javascript" src="js/exif.js" ></script>  
  10.     <script>  
  11.   
  12.     </script>  
  13. </head>  
  14. <body>  
  15.     <div style="height: 50px; line-height: 50px;text-align: center;border-bottom: 1px solid #171E28;">  
  16.             上传图片:  
  17.             <input type="file" accept="image/*" id="uploadImage" capture="camera" οnchange="selectFileImage(this);" />  
  18.         </div>  
  19.         <div style="margin-top: 10px;">  
  20.             <img alt="preview" src="" id="myImage"/>  
  21.         </div>  
  22. </body>  
  23. </html>  
uploadImage.js如下:

[javascript]  view plain  copy
  1. function selectFileImage(fileObj) {  
  2.     var file = fileObj.files['0'];  
  3.     //图片方向角 added by lzk  
  4.     var Orientation = null;  
  5.       
  6.     if (file) {  
  7.         console.log("正在上传,请稍后...");  
  8.         var rFilter = /^(image\/jpeg|image\/png)$/i; // 检查图片格式  
  9.         if (!rFilter.test(file.type)) {  
  10.             //showMyTips("请选择jpeg、png格式的图片", false);  
  11.             return;  
  12.         }  
  13.         // var URL = URL || webkitURL;  
  14.         //获取照片方向角属性,用户旋转控制  
  15.         EXIF.getData(file, function() {  
  16.            // alert(EXIF.pretty(this));  
  17.             EXIF.getAllTags(this);   
  18.             //alert(EXIF.getTag(this, 'Orientation'));   
  19.             Orientation = EXIF.getTag(this'Orientation');  
  20.             //return;  
  21.         });  
  22.           
  23.         var oReader = new FileReader();  
  24.         oReader.onload = function(e) {  
  25.             //var blob = URL.createObjectURL(file);  
  26.             //_compress(blob, file, basePath);  
  27.             var image = new Image();  
  28.             image.src = e.target.result;  
  29.             image.onload = function() {  
  30.                 var expectWidth = this.naturalWidth;  
  31.                 var expectHeight = this.naturalHeight;  
  32.                   
  33.                 if (this.naturalWidth > this.naturalHeight && this.naturalWidth > 800) {  
  34.                     expectWidth = 800;  
  35.                     expectHeight = expectWidth * this.naturalHeight / this.naturalWidth;  
  36.                 } else if (this.naturalHeight > this.naturalWidth && this.naturalHeight > 1200) {  
  37.                     expectHeight = 1200;  
  38.                     expectWidth = expectHeight * this.naturalWidth / this.naturalHeight;  
  39.                 }  
  40.                 var canvas = document.createElement("canvas");  
  41.                 var ctx = canvas.getContext("2d");  
  42.                 canvas.width = expectWidth;  
  43.                 canvas.height = expectHeight;  
  44.                 ctx.drawImage(this, 0, 0, expectWidth, expectHeight);  
  45.                 var base64 = null;  
  46.                 //修复ios  
  47.                 if (navigator.userAgent.match(/iphone/i)) {  
  48.                     console.log('iphone');  
  49.                     //alert(expectWidth + ',' + expectHeight);  
  50.                     //如果方向角不为1,都需要进行旋转 added by lzk  
  51.                     if(Orientation != "" && Orientation != 1){  
  52.                         alert('旋转处理');  
  53.                         switch(Orientation){  
  54.                             case 6://需要顺时针(向左)90度旋转  
  55.                                 alert('需要顺时针(向左)90度旋转');  
  56.                                 rotateImg(this,'left',canvas);  
  57.                                 break;  
  58.                             case 8://需要逆时针(向右)90度旋转  
  59.                                 alert('需要顺时针(向右)90度旋转');  
  60.                                 rotateImg(this,'right',canvas);  
  61.                                 break;  
  62.                             case 3://需要180度旋转  
  63.                                 alert('需要180度旋转');  
  64.                                 rotateImg(this,'right',canvas);//转两次  
  65.                                 rotateImg(this,'right',canvas);  
  66.                                 break;  
  67.                         }         
  68.                     }  
  69.                       
  70.                     /*var mpImg = new MegaPixImage(image); 
  71.                     mpImg.render(canvas, { 
  72.                         maxWidth: 800, 
  73.                         maxHeight: 1200, 
  74.                         quality: 0.8, 
  75.                         orientation: 8 
  76.                     });*/  
  77.                     base64 = canvas.toDataURL("image/jpeg", 0.8);  
  78.                 }else if (navigator.userAgent.match(/Android/i)) {// 修复android  
  79.                     var encoder = new JPEGEncoder();  
  80.                     base64 = encoder.encode(ctx.getImageData(0, 0, expectWidth, expectHeight), 80);  
  81.                 }else{  
  82.                     //alert(Orientation);  
  83.                     if(Orientation != "" && Orientation != 1){  
  84.                         //alert('旋转处理');  
  85.                         switch(Orientation){  
  86.                             case 6://需要顺时针(向左)90度旋转  
  87.                                 alert('需要顺时针(向左)90度旋转');  
  88.                                 rotateImg(this,'left',canvas);  
  89.                                 break;  
  90.                             case 8://需要逆时针(向右)90度旋转  
  91.                                 alert('需要顺时针(向右)90度旋转');  
  92.                                 rotateImg(this,'right',canvas);  
  93.                                 break;  
  94.                             case 3://需要180度旋转  
  95.                                 alert('需要180度旋转');  
  96.                                 rotateImg(this,'right',canvas);//转两次  
  97.                                 rotateImg(this,'right',canvas);  
  98.                                 break;  
  99.                         }         
  100.                     }  
  101.                       
  102.                     base64 = canvas.toDataURL("image/jpeg", 0.8);  
  103.                 }  
  104.                 //uploadImage(base64);  
  105.                 $("#myImage").attr("src", base64);  
  106.             };  
  107.         };  
  108.         oReader.readAsDataURL(file);  
  109.     }  
  110. }  
  111.   
  112. //对图片旋转处理 added by lzk  
  113. function rotateImg(img, direction,canvas) {    
  114.         //alert(img);  
  115.         //最小与最大旋转方向,图片旋转4次后回到原方向    
  116.         var min_step = 0;    
  117.         var max_step = 3;    
  118.         //var img = document.getElementById(pid);    
  119.         if (img == null)return;    
  120.         //img的高度和宽度不能在img元素隐藏后获取,否则会出错    
  121.         var height = img.height;    
  122.         var width = img.width;    
  123.         //var step = img.getAttribute('step');    
  124.         var step = 2;    
  125.         if (step == null) {    
  126.             step = min_step;    
  127.         }    
  128.         if (direction == 'right') {    
  129.             step++;    
  130.             //旋转到原位置,即超过最大值    
  131.             step > max_step && (step = min_step);    
  132.         } else {    
  133.             step--;    
  134.             step < min_step && (step = max_step);    
  135.         }    
  136.         //img.setAttribute('step', step);    
  137.         /*var canvas = document.getElementById('pic_' + pid);   
  138.         if (canvas == null) {   
  139.             img.style.display = 'none';   
  140.             canvas = document.createElement('canvas');   
  141.             canvas.setAttribute('id', 'pic_' + pid);   
  142.             img.parentNode.appendChild(canvas);   
  143.         }  */  
  144.         //旋转角度以弧度值为参数    
  145.         var degree = step * 90 * Math.PI / 180;    
  146.         var ctx = canvas.getContext('2d');    
  147.         switch (step) {    
  148.             case 0:    
  149.                 canvas.width = width;    
  150.                 canvas.height = height;    
  151.                 ctx.drawImage(img, 0, 0);    
  152.                 break;    
  153.             case 1:    
  154.                 canvas.width = height;    
  155.                 canvas.height = width;    
  156.                 ctx.rotate(degree);    
  157.                 ctx.drawImage(img, 0, -height);    
  158.                 break;    
  159.             case 2:    
  160.                 canvas.width = width;    
  161.                 canvas.height = height;    
  162.                 ctx.rotate(degree);    
  163.                 ctx.drawImage(img, -width, -height);    
  164.                 break;    
  165.             case 3:    
  166.                 canvas.width = height;    
  167.                 canvas.height = width;    
  168.                 ctx.rotate(degree);    
  169.                 ctx.drawImage(img, -width, 0);    
  170.                 break;    
  171.         }    
  172.     }    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值