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 相关文章推荐
js实现兼容IE6与IE7的DIV高度
May 13 Javascript
调试Node.JS的辅助工具(NodeWatcher)
Jan 04 Javascript
JS命名空间的另一种实现
Aug 09 Javascript
js整数字符串转换为金额类型数据(示例代码)
Dec 26 Javascript
深入分析原生JavaScript事件
Dec 29 Javascript
js实现简单计算器
Nov 22 Javascript
常见JS验证脚本汇总
Dec 01 Javascript
浅析javascript异步执行函数导致的变量变化问题解决思路
May 13 Javascript
Vue render渲染时间戳转时间,时间转时间戳及渲染进度条效果
Jul 27 Javascript
vue Tab切换以及缓存页面处理的几种方式
Nov 05 Javascript
ZK中使用JS读取客户端txt文件内容问题
Nov 07 Javascript
解决vue net :ERR_CONNECTION_REFUSED报错问题
Aug 13 Javascript
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常用函数小技巧
2008/09/11 PHP
PHP基础学习之流程控制的实现分析
2013/04/28 PHP
定义php常量的详解
2013/06/09 PHP
php_pdo 预处理语句详解
2016/11/21 PHP
php使用QueryList轻松采集js动态渲染页面方法
2018/09/11 PHP
PHP实现时间日期友好显示实现代码
2019/09/08 PHP
基于mootools 1.3框架下的图片滑动效果代码
2011/04/22 Javascript
jQuery处理xml格式的返回数据(实例解析)
2013/11/28 Javascript
jQuery实现的一个tab切换效果内部还嵌有切换
2014/08/10 Javascript
详解AngularJS中自定义指令的使用
2015/06/17 Javascript
javascript实现3D变换的立体圆圈实例
2015/08/06 Javascript
谈谈React中的Render Props模式
2018/12/06 Javascript
jQuery实现左右两个列表框的内容相互移动功能示例
2019/01/27 jQuery
详解利用eventemitter2实现Vue组件通信
2019/11/04 Javascript
JS实现京东商品分类侧边栏
2020/12/11 Javascript
[03:39]2015国际邀请赛主赛事首日精彩回顾
2015/08/05 DOTA
Python类的基础入门知识
2008/11/24 Python
python复制文件代码实现
2013/12/23 Python
Python实现批量转换文件编码的方法
2015/07/28 Python
Python中使用urllib2模块编写爬虫的简单上手示例
2016/01/20 Python
python实现RSA加密(解密)算法
2016/02/17 Python
详解python中的json的基本使用方法
2016/12/21 Python
python中多个装饰器的执行顺序详解
2018/10/08 Python
Python实现的删除重复文件或图片功能示例【去重】
2019/04/23 Python
解决pyqt5中QToolButton无法使用的问题
2019/06/21 Python
Python socket模块方法实现详解
2019/11/05 Python
python 通过文件夹导入包的操作
2020/06/01 Python
毕业生求职简历的自我评价
2013/10/23 职场文书
领导检查欢迎词
2014/01/14 职场文书
房屋产权证明书
2014/10/15 职场文书
人事局接收函
2015/01/30 职场文书
水电工程师岗位职责
2015/02/13 职场文书
餐厅保洁员岗位职责
2015/04/10 职场文书
2016高考寄语或鼓励的话语
2015/12/04 职场文书
改进工作作风心得体会
2016/01/23 职场文书
Python实现简单的猜单词
2021/06/15 Python