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上如何旋轉進行詳細講解。
Canvas-圖片旋轉

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章