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 14 Javascript
JQUERY操作JSON实例代码
Feb 09 Javascript
JS中prototype关键字的功能介绍及使用示例
Jul 21 Javascript
jquery.hotkeys监听键盘按下事件keydown插件
May 11 Javascript
浅谈javascript面向对象程序设计
Jan 21 Javascript
Bootstrap打造一个左侧折叠菜单的系统模板(一)
May 17 Javascript
手机端 HTML5使用photoswipe.js仿微信朋友圈图片放大效果
Aug 25 Javascript
js正则表达式注册页面表单验证
Oct 11 Javascript
react-native动态切换tab组件的方法
Jul 07 Javascript
深入了解JS之作用域和闭包
Jun 16 Javascript
vuecli3.x中轻松4步带你使用tinymce的步骤
Jun 25 Javascript
vue实现登录功能
Dec 31 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
2014年最新推荐的10款 PHP 开发框架
2014/08/01 PHP
destoon切换城市后实现logo旁边显示地区名称的方法
2014/08/21 PHP
Yii2中如何使用modal弹窗(基本使用)
2016/05/30 PHP
PHP常见字符串操作函数与用法总结
2019/03/04 PHP
什么是PHP7中的孤儿进程与僵尸进程
2019/04/14 PHP
网页设计常用的一些技巧
2006/12/22 Javascript
Javascript实例教程(19) 使用HoTMetal(2)
2006/12/23 Javascript
另类调用flash无须激活的方法
2006/12/27 Javascript
JavaScript 变量基础知识
2009/11/07 Javascript
jquery原理以及学习技巧介绍
2015/11/11 Javascript
jquery密码强度校验
2015/12/02 Javascript
基于BootStrap Metronic开发框架经验小结【八】框架功能总体界面介绍
2016/05/12 Javascript
JS实现根据用户输入分钟进行倒计时功能
2016/11/14 Javascript
Vue.js中数据绑定的语法教程
2017/06/02 Javascript
深入理解Angular中的依赖注入
2017/06/26 Javascript
JavaScript 中Date对象的格式化代码方法汇总
2017/09/06 Javascript
AngularJS 实现购物车全选反选功能
2017/10/24 Javascript
解决betterScroll在vue中存在图片时,出现拉不动的问题
2018/09/27 Javascript
javascript实现简易聊天室
2019/07/12 Javascript
JS实现在线ps功能详解
2019/07/31 Javascript
详解vue中在循环中使用@mouseenter 和 @mouseleave事件闪烁问题解决方法
2020/04/07 Javascript
Element Carousel 走马灯的具体实现
2020/07/26 Javascript
[04:48]DOTA2上海特锦赛小组赛第三日 TOP10精彩集锦
2016/02/28 DOTA
[03:41]2018完美盛典-《Fight With Us》
2018/12/16 DOTA
python实现移位加密和解密
2019/03/22 Python
python如何实现从视频中提取每秒图片
2020/10/22 Python
Timberland美国官网:全球领先的户外品牌
2016/08/15 全球购物
shell程序中如何注释
2012/01/28 面试题
四下基层实施方案
2014/03/28 职场文书
工作疏忽、懈怠的检讨书
2014/09/11 职场文书
法院授权委托书格式
2014/09/28 职场文书
2014年前台个人工作总结
2014/11/14 职场文书
介绍信样本
2015/01/31 职场文书
开学典礼观后感
2015/06/15 职场文书
高中语文教材(文学文化常识大全一)
2019/08/13 职场文书
python3 实现mysql数据库连接池的示例代码
2021/04/17 Python