• js获取图片的EXIF,解决图片旋转问题


    相信大家在做项目的时候会遇到在canvas里加入图片时,图片发生90°,180°的旋转。当时的你肯定时懵逼的,为毛。
    其实这就是图片的EXIF搞的鬼。

    什么是EXIF

    简单来说,Exif 信息就是由数码相机在拍摄过程中采集一系列的信息,然后把信息放置在我们熟知的 JPEG/TIFF 文件的头部,也就是说 Exif信息是镶嵌在 JPEG/TIFF 图像文件格式内的一组拍摄参数,它就好像是傻瓜相机的日期打印功能一样,只不过 Exif信息所记录的资讯更为详尽和完备。Exif 所记录的元数据信息非常丰富,主要包含了以下几类信息:

    • 拍摄日期
    • 摄器材(机身、镜头、闪光灯等
    • 拍摄参数(快门速度、光圈F值、ISO速度、焦距、测光模式等
    • 图像处理参数(锐化、对比度、饱和度、白平衡等)
    • 图像描述及版权信息
    • GPS定位数据
    • 缩略图

    这里面就包含了图片的角度信息,就是说你用手机拍照时是不是倒着拍还是侧着拍,这些都是有记录的。
    接下来就是教大家怎么获取图片内的exif信息
    先给大家看看exif信息都存在哪里:(角度就在0x0112
    exif信息的地址

    // 这里的获取exif要将图片转ArrayBuffer对象,这里假设获取了图片的baes64
    // 步骤一
    // base64转ArrayBuffer对象
      function base64ToArrayBuffer(base64) {
        base64 = base64.replace(/^data:([^;]+);base64,/gmi, '');
        var binary = atob(base64);
        var len = binary.length;
        var buffer = new ArrayBuffer(len);
        var view = new Uint8Array(buffer);
        for (var i = 0; i < len; i++) {
          view[i] = binary.charCodeAt(i);
        }
        return buffer;
      }
    // 步骤二,Unicode码转字符串
    // ArrayBuffer对象 Unicode码转字符串
      function getStringFromCharCode(dataView, start, length) {
        var str = '';
        var i;
        for (i = start, length += start; i < length; i++) {
          str += fromCharCode(dataView.getUint8(i));
        }
        return str;
      }
    
    // 步骤三,获取jpg图片的exif的角度(在ios体现最明显)
      function getOrientation(arrayBuffer) {
        var dataView = new DataView(arrayBuffer);
        var length = dataView.byteLength;
        var orientation;
        var exifIDCode;
        var tiffOffset;
        var firstIFDOffset;
        var littleEndian;
        var endianness;
        var app1Start;
        var ifdStart;
        var offset;
        var i;
        // Only handle JPEG image (start by 0xFFD8)
        if (dataView.getUint8(0) === 0xFF && dataView.getUint8(1) === 0xD8) {
          offset = 2;
          while (offset < length) {
            if (dataView.getUint8(offset) === 0xFF && dataView.getUint8(offset + 1) === 0xE1) {
              app1Start = offset;
              break;
            }
            offset++;
          }
        }
        if (app1Start) {
          exifIDCode = app1Start + 4;
          tiffOffset = app1Start + 10;
          if (getStringFromCharCode(dataView, exifIDCode, 4) === 'Exif') {
            endianness = dataView.getUint16(tiffOffset);
            littleEndian = endianness === 0x4949;
    
            if (littleEndian || endianness === 0x4D4D /* bigEndian */) {
              if (dataView.getUint16(tiffOffset + 2, littleEndian) === 0x002A) {
                firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian);
    
                if (firstIFDOffset >= 0x00000008) {
                  ifdStart = tiffOffset + firstIFDOffset;
                }
              }
            }
          }
        }
        if (ifdStart) {
          length = dataView.getUint16(ifdStart, littleEndian);
    
          for (i = 0; i < length; i++) {
            offset = ifdStart + i * 12 + 2;
            if (dataView.getUint16(offset, littleEndian) === 0x0112 /* Orientation */) {
    
              // 8 is the offset of the current tag's value
              offset += 8;
    
              // Get the original orientation value
              orientation = dataView.getUint16(offset, littleEndian);
    
              // Override the orientation with its default value for Safari (#120)
              if (IS_SAFARI_OR_UIWEBVIEW) {
                dataView.setUint16(offset, 1, littleEndian);
              }
              break;
            }
          }
        }
        return orientation;
      }
    

    方法getStringFromCharCode(arrayBuffer)返回的orientation就是图片的方向也就是旋转的值,再对应下面的表,对图片进行处理

    orientation值 旋转角度
    1
    3 180°
    6 顺时针90°
    8 逆时针90°

    大家可以先判断图片Exif的orientation值再根据上表对应的旋转值,在canvas上对图片进行反方向旋转消除影响

    之后我会对canvas上如何旋转进行详细讲解。

  • 相关阅读:
    友链
    Vue打包后处理跨域
    es6 Promise
    express get和post数据
    Nodejs登陆注册应用
    bootstrap按钮
    vue-router
    vue--transition多个元素运动
    $ git push -u origin masterremote时出现错误: error: GH007: Your push would publish a private email address.
    vue.js监听
  • 原文地址:https://www.cnblogs.com/suyuanli/p/8168407.html
Copyright © 2020-2023  润新知