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宝典学习笔记(上)
Jan 10 Javascript
List Installed Software Features
Jun 11 Javascript
javascript各种复制代码收集
Sep 20 Javascript
使用PHP+JQuery+Ajax分页的实现
Apr 23 Javascript
js中单引号与双引号冲突问题解决方法
Oct 04 Javascript
Javascript Web Slider 焦点图示例源码
Oct 10 Javascript
jquery实现多屏多图焦点图切换特效的方法
May 04 Javascript
JS实现图片的不间断连续滚动的简单实例
Jun 03 Javascript
Bootstrap中点击按钮后变灰并显示加载中实例代码
Sep 23 Javascript
不使用script导入js文件的几种方法
Oct 27 Javascript
解析vue中的$mount
Dec 21 Javascript
最后说说Vue2 SSR 的 Cookies 问题
May 25 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解析字符串里所有URL地址的方法
2015/04/03 PHP
php实现Mysql简易操作类
2015/10/11 PHP
php实现在线通讯录功能(附源码)
2016/05/13 PHP
php大小写转换函数(strtolower、strtoupper)用法介绍
2017/11/17 PHP
php中字符串和整数比较的操作方法
2019/06/06 PHP
深入理解PHP+Mysql分布式事务与解决方案
2020/12/03 PHP
Javascript玩转继承(二)
2014/05/08 Javascript
jquery 实现返回顶部功能
2014/11/17 Javascript
60行js代码实现俄罗斯方块
2015/03/31 Javascript
简介JavaScript中toUpperCase()方法的使用
2015/06/06 Javascript
jQuery实现本地预览上传图片功能
2016/01/08 Javascript
详解javascript实现自定义事件
2016/01/19 Javascript
Bootstrap布局方式详解
2016/05/27 Javascript
Bootstrap编写导航栏和登陆框
2016/05/30 Javascript
AngularJS实现分页显示数据库信息
2016/07/01 Javascript
原生JS实现图片翻书效果
2017/02/16 Javascript
Vuex之理解Mutations的用法实例
2017/04/19 Javascript
Bootstrap Table 双击、单击行获取该行及全表内容
2018/08/31 Javascript
Node.js API详解之 timer模块用法实例分析
2020/05/07 Javascript
vue-router为激活的路由设置样式操作
2020/07/18 Javascript
JS中多层次排序算法的实现代码
2021/01/06 Javascript
wxPython框架类和面板类的使用实例
2014/09/28 Python
python使用opencv读取图片的实例
2017/08/17 Python
Python使用struct处理二进制的实例详解
2017/09/11 Python
python监控进程脚本
2018/04/12 Python
PyTorch读取Cifar数据集并显示图片的实例讲解
2018/07/27 Python
wxPython的安装与使用教程
2018/08/31 Python
python 6行代码制作月历生成器
2020/09/18 Python
python Timer 类使用介绍
2020/12/28 Python
同程旅游英文网站:LY.com
2018/11/13 全球购物
Windows和Linux动态库应用异同
2016/04/17 面试题
环保建议书600字
2014/05/14 职场文书
乡镇干部个人整改措施思想汇报
2014/10/10 职场文书
思品教学工作总结
2015/08/10 职场文书
奖学金发言稿(范文)
2019/08/21 职场文书
教你使用Pandas直接核算Excel中快递费用
2021/05/12 Python