JavaScript如何处理移动端拍摄图片旋转问题

 更新时间:2019年11月16日 15:21:10   作者:随遇而安、1314  
这篇文章主要告诉大家JavaScript如何处理移动端拍摄图片旋转问题,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了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实现函数缓存及应用场景

    在JavaScript中,可以通过函数缓存来提高函数的执行效率,本文就来介绍一下JavaScript实现函数缓存及应用场景,具有一定的参考价值,感兴趣的可以了解一下
    2024-01-01
  • 一文了解你不知道的JavaScript生成器篇

    一文了解你不知道的JavaScript生成器篇

    ES6引入了一个新的函数类型,发现它并不符合这种运行到结束的特性。这类新的函数被称为生成器。生成器的出现是我们知道原来有时代码并不会顺利的运行,可以通过暂停的方式进行异步回调,让我们摒弃了此前的认知。本文就来聊聊JavaScript中生成器的相关知识
    2022-11-11
  • javascript 页面只自动刷新一次

    javascript 页面只自动刷新一次

    记得meta标签当中有一个refresh的功能吗?这是让浏览的页面刷新并可以转到相应的页面,如果刷新本页的话就会造成重复的刷新,现在我们就试试用脚本来实现只让页面刷新一次.
    2009-07-07
  • javascript实现的鼠标链接提示效果生成器代码

    javascript实现的鼠标链接提示效果生成器代码

    javascript实现的鼠标链接提示效果生成器代码...
    2007-06-06
  • javascript jscroll模拟html元素滚动条

    javascript jscroll模拟html元素滚动条

    这里是自己在工作不太忙的时候写出来了一个用户可以自定义的滚动条jscroll,以下简称jscroll。jscroll默认只提供一种滚动条样式,部分样式来自google webstore ,其中有部分css3样式主要用于实现圆角,阴影效果
    2012-12-12
  • 构建一个JavaScript插件系统

    构建一个JavaScript插件系统

    这篇文章主要介绍了如何构建一个JavaScript插件系统,帮助大家更好的理解和使用JavaScript,感兴趣的朋友可以了解下
    2020-10-10
  • NodeJS的Promise的用法解析

    NodeJS的Promise的用法解析

    下面小编就为大家带来一篇NodeJS的Promise的用法解析。小编觉得挺不错的,现在分享给大家,也给大家做个参考
    2016-05-05
  • JS如何在不同平台实现多语言方式

    JS如何在不同平台实现多语言方式

    这篇文章主要介绍了JS如何在不同平台实现多语言方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • JS折半插入排序算法实例

    JS折半插入排序算法实例

    这篇文章主要介绍了JS折半插入排序算法,以完整实例形式较为详细的分析了JavaScript实现折半插入排序的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-12-12
  • JavaScript清除所有(多个)定时器的方法实战案例

    JavaScript清除所有(多个)定时器的方法实战案例

    定时器就是由JS提供了一些原生方法来实现延时去执行某一段代码,下面这篇文章主要给大家介绍了关于JavaScript清除所有(多个)定时器的方法,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-01-01

最新评论