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脚本
Dec 12 Javascript
javascript显示选择目录对话框的代码
Nov 10 Javascript
JavaScript初学者应注意的七个细节小结
Jan 30 Javascript
IE下写xml文件的两种方式(fso/saveAs)
Aug 05 Javascript
10分钟掌握XML、JSON及其解析
Dec 06 Javascript
Vue异步组件使用详解
Apr 08 Javascript
bootstrap table sum总数量统计实现方法
Oct 29 Javascript
浅谈React Event实现原理
Sep 20 Javascript
详解Vue中watch的详细用法
Nov 28 Javascript
微信小程序 button样式设置为图片的方法
Jun 19 Javascript
vue基于Echarts的拖拽数据可视化功能实现
Dec 04 Vue.js
javascript实现数字时钟效果
Feb 06 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
Laravel 5框架学习之数据库迁移(Migrations)
2015/04/08 PHP
PHP导入导出Excel代码
2015/07/07 PHP
最准确的php截取字符串长度函数
2015/10/29 PHP
jquery乱码与contentType属性设置问题解决方案
2013/01/07 Javascript
js 利用image对象实现图片的预加载提高访问速度
2013/03/29 Javascript
js jquery分别实现动态的文件上传操作按钮的添加和删除
2014/01/13 Javascript
JAVASCRIPT代码编写俄罗斯方块网页版
2015/11/26 Javascript
浅谈Vue.js中ref ($refs)用法举例总结
2017/12/19 Javascript
checkbox在vue中的用法小结
2018/11/13 Javascript
Element input树型下拉框的实现代码
2018/12/21 Javascript
详解如何写出一个利于扩展的vue路由配置
2019/05/16 Javascript
Vue组件之高德地图地址选择功能的实例代码
2019/06/21 Javascript
vue 扩展现有组件的操作
2020/08/14 Javascript
解决nuxt页面中mounted、created、watch执行两遍的问题
2020/11/05 Javascript
python3.x实现发送邮件功能
2018/05/22 Python
Python 新建文件夹与复制文件夹内所有内容的方法
2018/10/27 Python
在python中利用KNN实现对iris进行分类的方法
2018/12/11 Python
python实现在函数中修改变量值的方法
2019/07/16 Python
Python 等分切分数据及规则命名的实例代码
2019/08/16 Python
python异步编程 使用yield from过程解析
2019/09/25 Python
基于python2.7实现图形密码生成器的实例代码
2019/11/05 Python
python GUI库图形界面开发之PyQt5窗口布局控件QStackedWidget详细使用方法
2020/02/27 Python
python sklearn包——混淆矩阵、分类报告等自动生成方式
2020/02/28 Python
Python使用requests xpath 并开启多线程爬取西刺代理ip实例
2020/03/06 Python
一套软件测试笔试题
2014/07/25 面试题
完美实现CSS垂直居中的11种方法
2021/03/27 HTML / CSS
装修五一活动策划案
2014/01/23 职场文书
中英文求职信范文
2014/01/27 职场文书
2014两会学习心得:时代的发展
2014/03/17 职场文书
2015年事业单位工作总结
2015/04/27 职场文书
2016大学迎新欢迎词
2015/09/29 职场文书
礼貌问候语大全
2015/11/10 职场文书
2019经典广告词集锦!
2019/07/02 职场文书
《悬崖边的树》读后感2篇
2019/12/02 职场文书
Python 的演示平台支持 WSGI 接口的应用
2022/04/20 Python
Echarts如何重新渲染实例详解
2022/05/30 Javascript