若是你是爲了獲取 exif 解析後的信息,那麼你能夠看這篇 前端獲取圖片exif信息,經過 exif-js 來獲取的。html
看到這裏你要懵逼了,我爲何又要寫一遍。emmmm...由於我需求變了,直接拿到 exif 部分的數據,而後 base64 提交。(giao) 測試地址前端
可交換圖像文件格式(英語:Exchangeable image file format,官方簡稱 Exif),是專門爲 數碼相機的照片設定的,能夠記錄數碼照片的屬性信息和拍攝數據。
Exif 信息以 0xFFE1 做爲開頭標記,後兩個字節表示 Exif 信息的長度。因此 Exif 信息最大爲64 kb,而內部採用 TIFF 格式。git
基於這樣的規則,那其實我要獲取 exif 信息的串就很簡單了。github
// 獲取開始標記 ffe1_idx = blob.indexOf('ffe1'); // 截取後兩個字節,用來當長度 exifLength = blob.slice(ffe1_idx, ffe1_idx + 2) // 截取出exif exif = blob.slice(ffe1_idx, ffe1_idx + exifLength) // exif 處理成 base64 btoa(exif)
我是基於 exif.js
,使用了他內部的錯誤控制。segmentfault
由於 exif 是用於記錄數碼照片的屬性信息和拍攝數據,因此須要是 JPEG微信
if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) { console.log("Not a valid JPEG"); return { state: 1001, message: 'not a valid jpeg' }; }
前面咱們介紹了 Exif 信息以 0xFFE1 做爲開頭標記。
因此咱們直接找這個信息less
將 arrayBuffer 數據以 Uint8 解析並展現 Array.from(new Uint8Array(temp1)).map(v=>[v, v.toString(16).padStart(2, '0'), String.fromCharCode(v)])
var offset = 2, //頭兩位是類型標記因此跳過 length = file.byteLength, //文件長度 marker; while (offset < length) { if (dataView.getUint8(offset) != 0xFF) { if (debug) console.log("Not a valid marker at offset " + offset + ", found: " + dataView.getUint8(offset)); return { state: 1002, message: 'not a valid marker, something is wrong' }; } marker = dataView.getUint8(offset + 1); if (debug) console.log(marker); if (marker == 225) { if (debug) console.log("Found 0xFFE1 marker"); return readEXIFData( dataView, // 數據源 offset + 4 //跳過 0xffe1 和 長度位 } else { offset += 2 + dataView.getUint16(offset + 2); } }
function readEXIFData(file, start) { // 判斷是否是 exif 信息,開頭應該是字符串 Exif if (getStringFromDB(file, start, 4) != "Exif") { if (debug) console.log("Not valid EXIF data! " + getStringFromDB(file, start, 4)); return { state: 1003, message: "Not valid EXIF data! " + getStringFromDB(file, start, 4) }; } // 判斷是大數結尾仍是小數結尾。 var bigEnd, tiffOffset = start + 6; if (file.getUint16(tiffOffset) == 0x4949) { bigEnd = false; } else if (file.getUint16(tiffOffset) == 0x4D4D) { bigEnd = true; } else { if (debug) console.log("Not valid TIFF data! (no 0x4949 or 0x4D4D)"); return { state: 1004, message: "Not valid TIFF data! (no 0x4949 or 0x4D4D)" }; } if (file.getUint16(tiffOffset + 2, !bigEnd) != 0x002A) { if (debug) console.log("Not valid TIFF data! (no 0x002A)"); return { state: 1005, message: "Not valid TIFF data! (no 0x002A)" }; } var firstIFDOffset = file.getUint32(tiffOffset + 4, !bigEnd); if (firstIFDOffset < 0x00000008) { if (debug) console.log("Not valid TIFF data! (First offset less than 8)", file.getUint32(tiffOffset + 4, !bigEnd)); return { state: 1006, message: "Not valid TIFF data! (First offset less than 8)" }; } // 截取,這裏代碼講道理仍是能夠優化的。 var _start = tiffOffset - 10; var _end = parseInt(Array.from(new Uint8Array(file.buffer.slice(start-2,start))).map(v=>v.toString(16)).join(''), 16)+start-2 return { state: 1000, data: btoa(Array.from(new Uint8Array(file.buffer.slice(_start, _end))).map(v => String.fromCharCode(v)).join('')) } }
歡迎你們關注個人公衆號。有疑問也能夠加個人微信前端交流羣。
測試