1. 程式人生 > >js獲取圖片的EXIF,解決圖片旋轉問題

js獲取圖片的EXIF,解決圖片旋轉問題

exif source 角度 function 平衡 mar uiwebview rom can

相信大家在做項目的時候會遇到在canvas裏加入圖片時,圖片發生90°,180°的旋轉。當時的你肯定時懵逼的,為毛。
其實這就是圖片的EXIF搞的鬼。

什麽是EXIF

簡單來說,Exif 信息就是由數碼相機在拍攝過程中采集一系列的信息,然後把信息放置在我們熟知的 JPEG/TIFF 文件的頭部,也就是說 Exif信息是鑲嵌在 JPEG/TIFF 圖像文件格式內的一組拍攝參數,它就好像是傻瓜相機的日期打印功能一樣,只不過 Exif信息所記錄的資訊更為詳盡和完備。Exif 所記錄的元數據信息非常豐富,主要包含了以下幾類信息:

  • 拍攝日期
  • 攝器材(機身、鏡頭、閃光燈等
  • 拍攝參數(快門速度、光圈F值、ISO速度、焦距、測光模式等
  • 圖像處理參數(銳化、對比度、飽和度、白平衡等)
  • 圖像描述及版權信息
  • GPS定位數據
  • 縮略圖

這裏面就包含了圖片的角度信息,就是說你用手機拍照時是不是倒著拍還是側著拍,這些都是有記錄的。
接下來就是教大家怎麽獲取圖片內的exif信息
先給大家看看exif信息都存在哪裏:(角度就在0x0112
技術分享圖片

// 這裏的獲取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上如何旋轉進行詳細講解。

js獲取圖片的EXIF,解決圖片旋轉問題