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

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

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

利用exif.js读取照片的拍摄信息,这里主要用到Orientation属性。

Orientation属性说明如下:

下面就直接上代码了。

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

自己写的是uploadImage.js。

html5测试页面如下:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
  <title>图片上传</title>
  <script type="text/javascript" src="js/jquery-1.8.3.js"></script>
  <script type="text/javascript" src="js/uploadPicture/uploadImage.js" ></script>
    <script type="text/javascript" src="js/exif.js" ></script>
  <script> 

  </script>
</head>
<body>
  <div style="height: 50px; line-height: 50px;text-align: center;border-bottom: 1px solid #171E28;">
      上传图片:
      <input type="file" accept="image/*" id="uploadImage" capture="camera" onchange="selectFileImage(this);" />
    </div>
    <div style="margin-top: 10px;">
      <img alt="preview" src="" id="myImage"/>
    </div>
</body>
</html>

uploadImage.js如下:

function selectFileImage(fileObj) {
  var file = fileObj.files['0'];
  //图片方向角 added by lzk
  var Orientation = null; 

  if (file) {
    console.log("正在上传,请稍后...");
    var rFilter = /^(image\/jpeg|image\/png)$/i; // 检查图片格式
    if (!rFilter.test(file.type)) {
      //showMyTips("请选择jpeg、png格式的图片", false);
      return;
    }
    // var URL = URL || webkitURL;
    //获取照片方向角属性,用户旋转控制
    EXIF.getData(file, function() {
      // alert(EXIF.pretty(this));
      EXIF.getAllTags(this);
      //alert(EXIF.getTag(this, 'Orientation'));
      Orientation = EXIF.getTag(this, 'Orientation');
      //return;
    }); 

    var oReader = new FileReader();
    oReader.onload = function(e) {
      //var blob = URL.createObjectURL(file);
      //_compress(blob, file, basePath);
      var image = new Image();
      image.src = e.target.result;
      image.onload = function() {
        var expectWidth = this.naturalWidth;
        var 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;
        }
        var canvas = document.createElement("canvas");
        var ctx = canvas.getContext("2d");
        canvas.width = expectWidth;
        canvas.height = expectHeight;
        ctx.drawImage(this, 0, 0, expectWidth, expectHeight);
        var base64 = null;
        //修复ios
        if (navigator.userAgent.match(/iphone/i)) {
          console.log('iphone');
          //alert(expectWidth + ',' + expectHeight);
          //如果方向角不为1,都需要进行旋转 added by lzk
          if(Orientation != "" && Orientation != 1){
            alert('旋转处理');
            switch(Orientation){
              case 6://需要顺时针(向左)90度旋转
                alert('需要顺时针(向左)90度旋转');
                rotateImg(this,'left',canvas);
                break;
              case 8://需要逆时针(向右)90度旋转
                alert('需要顺时针(向右)90度旋转');
                rotateImg(this,'right',canvas);
                break;
              case 3://需要180度旋转
                alert('需要180度旋转');
                rotateImg(this,'right',canvas);//转两次
                rotateImg(this,'right',canvas);
                break;
            }
          } 

          /*var mpImg = new MegaPixImage(image);
          mpImg.render(canvas, {
            maxWidth: 800,
            maxHeight: 1200,
            quality: 0.8,
            orientation: 8
          });*/
          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);
        }else{
          //alert(Orientation);
          if(Orientation != "" && Orientation != 1){
            //alert('旋转处理');
            switch(Orientation){
              case 6://需要顺时针(向左)90度旋转
                alert('需要顺时针(向左)90度旋转');
                rotateImg(this,'left',canvas);
                break;
              case 8://需要逆时针(向右)90度旋转
                alert('需要顺时针(向右)90度旋转');
                rotateImg(this,'right',canvas);
                break;
              case 3://需要180度旋转
                alert('需要180度旋转');
                rotateImg(this,'right',canvas);//转两次
                rotateImg(this,'right',canvas);
                break;
            }
          } 

          base64 = canvas.toDataURL("image/jpeg", 0.8);
        }
        //uploadImage(base64);
        $("#myImage").attr("src", base64);
      };
    };
    oReader.readAsDataURL(file);
  }
} 

//对图片旋转处理 added by lzk
function rotateImg(img, direction,canvas) {
    //alert(img);
    //最小与最大旋转方向,图片旋转4次后回到原方向
    var min_step = 0;
    var max_step = 3;
    //var img = document.getElementById(pid);
    if (img == null)return;
    //img的高度和宽度不能在img元素隐藏后获取,否则会出错
    var height = img.height;
    var width = img.width;
    //var step = img.getAttribute('step');
    var 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);
    }
    //img.setAttribute('step', step);
    /*var canvas = document.getElementById('pic_' + pid);
    if (canvas == null) {
      img.style.display = 'none';
      canvas = document.createElement('canvas');
      canvas.setAttribute('id', 'pic_' + pid);
      img.parentNode.appendChild(canvas);
    } */
    //旋转角度以弧度值为参数
    var degree = step * 90 * Math.PI / 180;
    var 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;
    }
  }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索js
, 旋转
exif
exif javascript、java exif 旋转、js exif 旋转、android exif 旋转、exif 旋转,以便于您获取更多的相关知识。

时间: 2025-01-31 09:17:42

详解利用exif.js解决ios手机上传竖拍照片旋转90度问题_javascript技巧的相关文章

微信JSSDK多图片上传并且解决IOS系统上传一直加载的问题

微信多图片上传必须挨个上传,也就是不能并行,得串行: 那么我们可以定义一个如下所示的上传函数: var serverIds = []; function uploadImages(localImagesIds) { if (localImagesIds.length === 0) { $.showPreloader('正在提交数据...'); $('form').submit(); } wx.uploadImage({ localId: localImagesIds[0], // 需要上传的图片

JS自定义函数对web前端上传的文件进行类型大小判断_javascript技巧

废话不多说了直接给大家贴js代码了.具体代码如下所示: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <me

详解利用Keepalived+Nginx解决站点高可用性

背景: 公司官网PV不高,压力不大,所以公司给出两台服务器来提供官网web服务,毕竟是公司门面,不能出现问题!所以就需要一个轻量级web容灾方案! 方案: 利用keepalived+nginx实现官网web的高可用性 两台服务器一台为主,一台为备机,使两台机器公用一个虚拟IP,当主服务器宕机,106.3.32.6这个IP会自动切换到备机上,前端机恢复之后再自动切换回主服务机 然后,主服务机和备机利用rsync实现实时同步数据, rsync的安装配置可以参照我之前的一篇文章:http://cuim

详解Ajax和form+iframe 实现文件上传的方法(两种方式)_AJAX相关

自从有html5之后,文件上传变的非常简单.很方便的解决了项目中需要用到的文件上传功能.HTML5支持多图片上传,而且支持ajax上传,而且支持上传之前图片的预览,而且支持图片拖拽上传,而且还是纯粹利用file控件实现,JS代码寥寥,想不让人称赞都难啊! HTML5Ajax上传 html5的上传实现,是需要file控件以及XMLHttpRequest请求.下面是我封装的一个上传插件: function fileUpload(options) { var opts = options || {};

详解JavaScript对Date对象的操作问题(生成一个倒数7天的数组)_javascript技巧

问题描述: 使用JavaScript生成一个倒数7天的数组. 比如今天是10月1号,生成的数组是["9月25号","9月26号","9月27号","9月28号","9月29号","9月30号","10月1号"]. 这个难点就是需要判断这个月份(可能还需要上一个月份)是30天还是31天,而且还有瑞年的2月28天或者29天. 解答思路: 不需要那么复杂,在js中非常简单,

js实现支持手机滑动切换的轮播图片效果实例_javascript技巧

本文实例讲述了js实现支持手机滑动切换的轮播图片效果的方法.分享给大家供大家参考.具体如下: 运行效果如下: 完整实例代码点击此处本站下载. 使用方法案例: <script type="text/javascript" src="../src/zepto.js"></script> <script type="text/javascript" src="../src/carousel-image.js&qu

js获取上传文件的绝对路径实现方法_javascript技巧

在html中 <input type="file" id="importFile" /> <input type="button" onclick="upload()"/> <script> function upload() { var filename = document.getElementById("importFile").value; // 这时的filen

js获取判断上传文件后缀名的示例代码_javascript技巧

复制代码 代码如下: function lastname(){ //获取欲上传的文件路径var filepath = document.getElementById("file1").value; //为了避免转义反斜杠出问题,这里将对其进行转换var re = /(\\+)/g; var filename=filepath.replace(re,"#");//对路径字符串进行剪切截取var one=filename.split("#");//获

js 上传文件预览的简单实例_javascript技巧

1. FILE API html5提供了FIle和FileReader两个方法,可以读取文件信息并读取文件. 2. example <html> <body> <div id="test-image-preview" style="border: 1px solid rgb(204, 204, 204); width: 100%; height: 200px; background-size: contain; background-repeat