JavaScript如何处理移动端拍摄图片旋转问题


Posted in Javascript onNovember 16, 2019

本文实例为大家分享了js移动端拍摄图片旋转的具体代码,供大家参考,具体内容如下

第一步:引入exif-js

<script src="https://cdn.jsdelivr.net/npm/exif-js@2.3.0/exif.min.js"></script>

第二步:

/**
 * 处理图片文件(处理移动端拍摄图片旋转问题)
 * fileObj.file 图片文件独享
 * fileObj.resolution 在指定图片格式为 image/jpeg 或 image/webp的情况下,可以从 0 到 1 的区间内选择图片的质量。
 * fileObj.fileType 输入的文件类型,1 file对象,2 blob对象,3 base64字符串
 * fileObj.fileName 输出的文件名称,默认为picture.jpeg
 * fileObj.callback 回调函数
 */
function handleImageFile(fileObj) {
  // 给参数附初始值
  fileObj.fileName = fileObj.hasOwnProperty("fileName") ? "images/" + fileObj.fileName : "images/picture.jpeg";
  // 获取文件类型
  var fType = fileObj.file.type;
  if (fType.indexOf("image") === -1) return fileObj.callback({
    status: 500,
    message: "文件类型不正确",
    data: null
  });
  if (!EXIF) return fileObj.callback({
    status: 500,
    message: "EXIF 不存在",
    data: null
  });
  if (fileObj.file) {
    // 获取照片方向角属性,用户旋转控制
    EXIF.getData(fileObj.file, function () {
      var orientation = EXIF.getTag(this, 'Orientation');
      var oReader = new FileReader();
      oReader.onload = function (e) {
        var image = new Image();
        image.src = e.target.result;
        image.onload = function () {
          var canvas = document.createElement("canvas");
          var ctx = canvas.getContext("2d");
          var resultFile = null;
          var ua = navigator.userAgent;
          canvas.width = this.naturalWidth;
          canvas.height = this.naturalHeight;
          ctx.drawImage(this, 0, 0, this.naturalWidth, this.naturalHeight);
          // android终端
          var isAdr = ua.indexOf("Android") > -1 || ua.indexOf("Adr") > -1;
          // ios终端
          var isIOS = ua.indexOf("iPhone") > -1 || ua.indexOf("iOS") > -1;
          // 修复ios 或 Android
          if (isIOS || isAdr) {
            // 如果方向角不为1,都需要进行旋转
            if (orientation && orientation !== "" && orientation !== 1) {
              switch (orientation) {
                case 6: // 需要顺时针(向左)90度旋转
                  rotateImg(this, "left", canvas);
                  break;
                case 8: // 需要逆时针(向右)90度旋转
                  rotateImg(this, "right90", canvas);
                  break;
                case 3: // 需要180度旋转,转两次
                  rotateImg(this, "right180", canvas);
                  break;
              }
            }
            resultFile = canvas.toDataURL("image/jpeg", fileObj.resolution);
          } else {
            resultFile = canvas.toDataURL("image/jpeg", fileObj.resolution);
          }
          switch (fileObj.fileType) {
            case 1:
            case 2:
              fileObj.callback({
                status: 200,
                message: "success",
                data: dataURLtoFile(resultFile, fileObj.fileType, fileObj.fileName)
              });
              break;
            case 3:
              fileObj.callback({
                status: 200,
                message: "success",
                data: resultFile
              });
              break;
            default:
              break;
          }
        };
      };
      oReader.readAsDataURL(fileObj.file);
    });
  } else {
    return fileObj.callback({
      status: 500,
      message: "文件不存在",
      data: null
    });
  }
  /**
   * 旋转图片
   */
  function rotateImg(img, direction, canvas) {
    if (img === null) return;
    // 最小与最大旋转方向,图片旋转4次后回到原方向
    var minStep = 0;
    var maxStep = 3;
    // img的高度和宽度不能在img元素隐藏后获取,否则会出错
    var width = img.width;
    var height = img.height;
    var step = 2;
    if (step === null) step = minStep;
    if (direction === "right90") {
      step++;
      step > maxStep && (step = minStep);
    } else if(direction === "right180") {
      step = 2;
    } else {
      step--;
      step < minStep && (step = maxStep);
    }
    // 旋转角度以弧度值为参数
    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, width, height);
        break;
      case 1:
        canvas.width = height;
        canvas.height = width;
        ctx.rotate(degree);
        ctx.drawImage(img, 0, -height, width, height);
        break;
      case 2:
        canvas.width = width;
        canvas.height = height;
        ctx.rotate(degree);
        ctx.drawImage(img, -width, -height, width, height);
        break;
      case 3:
        canvas.width = height;
        canvas.height = width;
        ctx.rotate(degree);
        ctx.drawImage(img, -width, 0, width, height);
        break;
    }
  }
  /**
   * type:1 file对象,2 blob对象
   */
  function dataURLtoFile(dataurl, type, filename) {
    var arr = dataurl.split(',');
    var mime = arr[0].match(/:(.*?);/)[1];
    var bstr = atob(arr[1]);
    var n = bstr.length;
    var u8arr = new Uint8Array(n);
    while (n--) {
      u8arr[n] = bstr.charCodeAt(n);
    }
    if (type === 1) { // 转换成file对象
      return new File([u8arr], filename, {
        type: mime
      });
    } else { // 转换成成blob对象
      return new Blob([u8arr], {
        type: mime
      });
    }
  }
}

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

Javascript 相关文章推荐
jquery select(列表)的操作(取值/赋值)
Mar 16 Javascript
解决JS浮点数运算出现Bug的方法
Mar 12 Javascript
js获取url中的参数且参数为中文时通过js解码
Mar 19 Javascript
js获取UserControl内容为拼html时提供方便
Nov 02 Javascript
JavaScript中的继承之类继承
May 01 Javascript
Javascript基础_嵌入图像的简单实现
Jun 14 Javascript
Bootstrap插件全集
Jul 18 Javascript
AngularJS入门教程之Helloworld示例
Dec 25 Javascript
JavaScript实现邮箱后缀提示功能的示例代码
Dec 13 Javascript
微信小程序动态显示项目倒计时
Jun 20 Javascript
WebStorm中如何将自己的代码上传到github示例详解
Oct 28 Javascript
vue+openlayers绘制省市边界线
Dec 24 Vue.js
JS Ajax请求会话过期处理问题解决方法分析
Nov 16 #Javascript
vue中注册自定义的全局js方法
Nov 15 #Javascript
微信sdk实现禁止微信分享(使用原生php实现)
Nov 15 #Javascript
微信JSSDK实现打开摄像头拍照再将相片保存到服务器
Nov 15 #Javascript
微信小程序自定义导航栏(模板化)
Nov 15 #Javascript
在node环境下parse Smarty模板的使用示例代码
Nov 15 #Javascript
微信小程序自定义头部导航栏(组件化)
Nov 15 #Javascript
You might like
php上的memcache和memcached两个pecl库
2010/03/29 PHP
Drupal7连接多个数据库及常见问题解决
2014/03/02 PHP
php查询mysql数据库并将结果保存到数组的方法
2015/03/18 PHP
PHP实现导出带样式的Excel
2016/08/28 PHP
php创建类并调用的实例方法
2019/09/25 PHP
在JavaScript中,为什么要尽可能使用局部变量?
2009/04/06 Javascript
单独使用CKFinder选择图片的方法
2010/08/21 Javascript
JQuery小知识
2010/10/15 Javascript
分享精心挑选的23款美轮美奂的jQuery 图片特效插件
2012/08/14 Javascript
详解vue.js之绑定class和style的示例代码
2017/08/24 Javascript
echarts设置图例颜色和地图底色的方法实例
2018/08/01 Javascript
nodejs log4js 使用详解
2019/05/31 NodeJs
vue 虚拟DOM的原理
2020/10/03 Javascript
基于p5.js 2D图像接口的扩展(交互实现)
2020/11/30 Javascript
[57:18]DOTA2上海特级锦标赛主赛事日 - 1 败者组第一轮#3VP VS VG
2016/03/03 DOTA
[01:04:14]VP vs TNC 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/20 DOTA
Python中Iterator迭代器的使用杂谈
2016/06/20 Python
Python科学计算包numpy用法实例详解
2018/02/08 Python
Python使用sort和class实现的多级排序功能示例
2018/08/15 Python
Python3.5面向对象程序设计之类的继承和多态详解
2019/04/24 Python
Python原始套接字编程实例解析
2020/01/29 Python
python 项目目录结构设置
2020/02/14 Python
Python中用pyinstaller打包时的图标问题及解决方法
2020/02/17 Python
详解Python修复遥感影像条带的两种方式
2020/02/23 Python
在python里使用await关键字来等另外一个协程的实例
2020/05/04 Python
Python实现Appium端口检测与释放的实现
2020/12/31 Python
linux面试题参考答案(11)
2012/05/01 面试题
自动化职业生涯规划书范文
2014/01/03 职场文书
岗位职责说明书
2014/05/07 职场文书
汽车运用工程专业求职信
2014/06/18 职场文书
2014预备党员批评与自我批评思想汇报
2014/09/20 职场文书
2019数学教师下学期工作总结
2019/06/27 职场文书
如何使用Python对NetCDF数据做空间相关分析
2021/04/21 Python
windows下快速安装nginx并配置开机自启动的方法
2021/05/11 Servers
忆童年!用Python实现愤怒的小鸟游戏
2021/06/07 Python
python数字转对应中文的方法总结
2021/08/02 Python