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 屏蔽一个区域内的所有元素,禁止输入
Oct 22 Javascript
『jQuery』.html(),.text()和.val()的概述及使用
Apr 22 Javascript
js实现瀑布流的一种简单方法实例分享
Nov 04 Javascript
jquery通过closest选择器修改上级元素的方法
Mar 17 Javascript
jQuery实现径向动画菜单效果
Jul 17 Javascript
原生js制作日历控件实例分享
Apr 06 Javascript
Jquery Easyui选项卡组件Tab使用详解(10)
Dec 18 Javascript
React-Native之定时器Timer的实现代码
Oct 04 Javascript
Vuejs中使用markdown服务器端渲染的示例
Nov 22 Javascript
AngularJS模态框模板ngDialog的使用详解
May 11 Javascript
vue在index.html中引入静态文件不生效问题及解决方法
Apr 29 Javascript
Vue+scss白天和夜间模式切换功能的实现方法
Jan 05 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(4) php 函数 补充2
2010/02/15 PHP
PHP cURL初始化和执行方法入门级代码
2015/05/28 PHP
利用PHP命令行模式采集股票趋势信息
2016/08/09 PHP
PHP自定义函数实现格式化秒的方法
2016/09/14 PHP
IE6下出现JavaScript未结束的字符串常量错误的解决方法
2010/11/21 Javascript
两种常用的javascript数组去重方法思路及代码
2013/03/26 Javascript
jquery获得keycode的示例代码
2013/12/30 Javascript
用jQuery与JSONP轻松解决跨域访问的问题
2014/02/04 Javascript
使用jquery实现以post打开新窗口
2014/03/19 Javascript
js实现仿百度瀑布流的方法
2015/02/05 Javascript
微信小程序 轮播图swiper详解及实例(源码下载)
2017/01/11 Javascript
关于AngularJs数据的本地存储详解
2017/01/20 Javascript
javascript基本数据类型和转换
2017/03/17 Javascript
Form表单上传文件(type=&quot;file&quot;)的使用
2017/08/03 Javascript
Angular动画实现的2种方式以及添加购物车动画实例代码
2018/08/09 Javascript
深入学习js函数的隐式参数 arguments 和 this
2019/06/24 Javascript
vue实现公告栏文字上下滚动效果的示例代码
2020/06/16 Javascript
[01:00]一分钟回顾2018DOTA2亚洲邀请赛现场活动
2018/04/07 DOTA
python实现堆和索引堆的代码示例
2018/03/19 Python
python实现汉诺塔算法
2021/03/01 Python
python对Excel按条件进行内容补充(推荐)
2019/11/24 Python
CSS3田字格列表的样式编写方法
2018/11/22 HTML / CSS
详解canvas在圆弧周围绘制文本的两种写法
2018/05/22 HTML / CSS
h5使用canvas画布实现手势解锁
2019/01/04 HTML / CSS
Linux机考试题
2015/07/17 面试题
个人简历自我评价八例
2013/10/31 职场文书
工厂厂长岗位职责
2013/11/08 职场文书
应届大学生求职的自我评价
2013/11/17 职场文书
初中地理教学反思
2014/01/11 职场文书
幼师个人总结范文
2015/02/28 职场文书
试用期自我评价范文
2015/03/10 职场文书
2016高考寄语或鼓励的话语
2015/12/04 职场文书
500字作文之周记
2019/12/13 职场文书
最新最全的手机号验证正则表达式
2022/02/24 Javascript
vue+echarts实现多条折线图
2022/03/21 Vue.js
Redis 异步机制
2022/05/15 Redis