/**
* http://blog.csdn.net/libins/article/details/50973498
* http://blog.csdn.net/han_jiang_xue/article/details/8266207
* http://www.360doc.com/content/17/0219/18/37253146_630338662.shtml
* 默認角度
* 0° =1
* 順時針90° =6
* 逆時針90° =8
* 180° =3
*/
const defaultOrientation = 1
/**
* https://github.com/exif-js/exif-js/blob/master/exif.js#L107
*/
const TiffTags = 0x0112
/**
* https://github.com/exif-js/exif-js/blob/master/exif.js#L534
* @param {*} dataView
* @param {*} dirStart
* @param {*} littleEndian
*/
const readTagValue = (dataView, dirStart, littleEndian) => {
// 第一個 圖像文件目錄Image File Directory(IFD)
var entries = dataView.getUint16(dirStart, littleEndian)
var entryOffset
var i
for (i = 0; i < entries; i++) {
// Directory Entry(DE)
entryOffset = dirStart + i * 12 + 2
if (TiffTags === dataView.getUint16(entryOffset, littleEndian)) {
// short, 16 bit int
return dataView.getUint16(entryOffset + 8, littleEndian)
}
}
return defaultOrientation
}
/**
* https://github.com/exif-js/exif-js/blob/master/exif.js#L394
* https://github.com/exif-js/exif-js/blob/master/exif.js#L651
* @param {*} arrayBuf reader.readAsArrayBuffer(file)
*/
const readExif = (arrayBuf) => {
var dataView = new DataView(arrayBuf)
var offset = 2
var length = dataView.byteLength
while (offset < length) {
// 判斷是不是標記 0xFF+標記號(1個字節(jié))+數(shù)據(jù)大小描述符(2個字節(jié))+數(shù)據(jù)內(nèi)容(n個字節(jié))
if (dataView.getUint8(offset) !== 0xFF) break
// Exif 使用APP1(0xFFE1)
if (dataView.getUint8(offset + 1) === 0xE1) {
offset = offset + 4
// Exif 數(shù)據(jù)開始于ASCII字符 "Exif" 和2個字節(jié)的0x00, 后面才是 Exif的數(shù)據(jù)
// E = 0x45 | x = 0x78 | i =0x69 | f =0x66
if (dataView.getUint32(offset) !== (0x45000000 | 0x780000 | 0x6900 | 0x66)) {
return defaultOrientation
}
var littleEndian
offset = offset + 6
// TIFF格式中前8個字節(jié)是 TIFF 頭. 其中最開始的前2個字節(jié)定義了 TIFF 數(shù)據(jù)的字節(jié)序.
// 如果這個值是 0x4949="II"的話, 就表示按照 "Intel" 的字節(jié)序(Little Endian) 來排列數(shù)據(jù).
// 如果是 0x4d4d="MM",則說明按照 "Motorola" 的字節(jié)序(Big Endian)來排列數(shù)據(jù)
// 隨后的兩個字節(jié)是一個2字節(jié)長度的固定值 0x002A. ,
// getUint16 第二個參數(shù) 如果為 false 或未定義,則應(yīng)讀取一個 big-endian 值,否則應(yīng)讀取一個 little-endian 值。
// 如果數(shù)據(jù)使用 Intel 字節(jié)序, 則這兩個 字節(jié)的數(shù)據(jù)排列為"0x2a,0x00".
// 如果是 Motorola 的, 則是 "0x00,0x2a"
if (dataView.getUint16(offset) === 0x4949 && dataView.getUint16(offset + 2, true) === 0x2A00) {
littleEndian = true
} else if (dataView.getUint16(offset) === 0x4D4D && dataView.getUint16(offset + 2) === 0x002A) {
littleEndian = false
} else {
return defaultOrientation
}
var firstIFDOffset = dataView.getUint32(offset + 4, littleEndian)
// TIFF頭的最后的 4個字節(jié)是到第一個IFD 偏移量的值是 '0x00000008'.
if (firstIFDOffset < 0x00000008) {
return defaultOrientation
}
return readTagValue(dataView, offset + firstIFDOffset, littleEndian)
} else {
offset += 2 + dataView.getUint16(offset + 2)
}
}
return defaultOrientation
}
圖片的Exif信息
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
推薦閱讀更多精彩內(nèi)容
- 大家都知道,相機在照相時是會為照片生成Exif,里面包含有拍照時間、圖片尺寸、旋轉(zhuǎn)角度、GPS定位等信息,有時候,...
- 1.Exif簡介 可交換圖像文件格式常被簡稱為Exif(Exchangeable image file forma...
- 信任是最寶貴的財富和最珍貴的資源。如果你建立了信任,它會影響你生活的方方面面,無論是事業(yè)還是個人生活。如果你失去了...