zoukankan      html  css  js  c++  java
  • 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上对图片进行反方向旋转消除影响

  • 相关阅读:
    通过HttpListener实现简单的Http服务
    WCF心跳判断服务端及客户端是否掉线并实现重连接
    NHibernate初学六之关联多对多关系
    NHibernate初学五之关联一对多关系
    EXTJS 4.2 资料 跨域的问题
    EXTJS 4.2 资料 控件之Grid 那些事
    EXTJS 3.0 资料 控件之 GridPanel属性与方法大全
    EXTJS 3.0 资料 控件之 Toolbar 两行的用法
    EXTJS 3.0 资料 控件之 combo 用法
    EXTJS 4.2 资料 控件之 Store 用法
  • 原文地址:https://www.cnblogs.com/zhangyezi/p/13346101.html
Copyright © 2011-2022 走看看