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 相关文章推荐
javascript multibox 全选
Mar 22 Javascript
解析jQuery与其它js(Prototype)库兼容共存
Jul 04 Javascript
js判断数据类型如判断是否为数组是否为字符串等等
Jan 15 Javascript
JS二维数组的定义说明
Mar 03 Javascript
jQuery随手笔记之常用的jQuery操作DOM事件
Nov 29 Javascript
基于javascript实现简单计算器功能
Jan 03 Javascript
vue实现列表的添加点击
Dec 29 Javascript
js实现手机拍照上传功能
Jan 17 Javascript
浅谈Vuex@2.3.0 中的 state 支持函数申明
Nov 22 Javascript
vue.js实现会动的简历(包含底部导航功能,编辑功能)
Apr 08 Javascript
快速解决Vue、element-ui的resetFields()方法重置表单无效的问题
Aug 12 Javascript
vue项目在线上服务器访问失败原因分析
Aug 14 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语法(4)
2006/10/09 PHP
10个可以简化php开发过程的MySQL工具
2010/04/11 PHP
PHP中操作ini配置文件的方法
2013/04/25 PHP
Jquery Ajax的Get方式时需要注意URL地方
2011/04/07 Javascript
Jquery实现列表(隔行换色,全选,鼠标滑过当前行)效果实例
2013/06/09 Javascript
jquery实现初次打开有动画效果的网页TAB切换代码
2015/09/06 Javascript
高效利用Angular中内置服务$http、$location等
2016/03/22 Javascript
一起学写js Calender日历控件
2016/04/14 Javascript
通用无限极下拉菜单的实现代码
2016/05/31 Javascript
js实现旋转木马效果
2017/03/17 Javascript
JS基于正则表达式的替换操作(replace)用法示例
2017/04/28 Javascript
Node.js+jade抓取博客所有文章生成静态html文件的实例
2017/09/19 Javascript
你应该知道的几类npm依赖包管理详解
2017/10/06 Javascript
解决angularjs service中依赖注入$scope报错的问题
2018/10/02 Javascript
Next.js项目实战踩坑指南(笔记)
2018/11/29 Javascript
vue双向绑定数据限制长度的方法
2019/11/04 Javascript
Javascript原生ajax请求代码实例
2020/02/20 Javascript
浅谈JS for循环中使用break和continue的区别
2020/07/21 Javascript
jquery实现简单自动轮播图效果
2020/07/29 jQuery
使用Vant完成通知栏Notify的提示操作
2020/11/11 Javascript
Python数据结构之Array用法实例
2014/10/09 Python
使用Python的Django框架结合jQuery实现AJAX购物车页面
2016/04/11 Python
python利用MethodType绑定方法到类示例代码
2017/08/27 Python
在python中利用GDAL对tif文件进行读写的方法
2018/11/29 Python
python关闭占用端口方式
2019/12/17 Python
python编写一个会算账的脚本的示例代码
2020/06/02 Python
基于django2.2连oracle11g解决版本冲突的问题
2020/07/02 Python
通过Python pyecharts输出保存图片代码实例
2020/11/25 Python
蛋白质世界:Protein World
2017/11/23 全球购物
几个常见的消息中间件(MOM)
2014/01/08 面试题
快餐店的创业计划书范文
2014/01/29 职场文书
干部选拔任用方案
2014/05/26 职场文书
党员干部观看《周恩来四个昼夜》思想汇报
2014/09/10 职场文书
一百条裙子读书笔记
2015/07/01 职场文书
2016大学生求职自荐信范文
2016/01/28 职场文书
PyTorch的Debug指南
2021/05/07 Python