当前位置 主页 > 网站技术 > 代码类 >

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

    栏目:代码类 时间:2019-11-16 18:05

    本文实例为大家分享了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
          });
        }
      }
    }