Created
May 16, 2019 10:12
-
-
Save laziel/f699c6f4abff32b1b7503968deb61e3c to your computer and use it in GitHub Desktop.
EXIF image orientation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Get image orientation from EXIF header | |
* | |
* Referenced: | |
* - https://gist.github.com/nezed/d536ccdace84c6f2ef13da47a8fd6bdb | |
* - https://gist.github.com/wonnage/9d2e73d9228f5a0b300d75babe2c3796 | |
* - https://github.com/blueimp/JavaScript-Load-Image/blob/master/js/load-image-meta.js | |
* | |
* @param {String} imageUrl | |
* @return {Promise} | |
*/ | |
async function getImageOrientation(imageUrl) { | |
try { | |
const arrayBuffer = await fetchAsArrayBuffer(imageUrl); | |
const dataView = new DataView(arrayBuffer.slice(0, 64 * 1024)); | |
// Check for the JPEG marker | |
if (dataView.getUint16(0, false) !== 0xFFD8) { | |
throw new Error(`File is not a .jpeg`); | |
} | |
let offset = 2; // advance past the jpeg header | |
while (offset < dataView.byteLength) { | |
const marker = dataView.getUint16(offset, false); | |
offset += 2; | |
if (marker == 0xFFE1) { // APP1 marker | |
// ascii hex values of the string 'Exif' | |
if (dataView.getUint32(offset += 2, false) !== 0x45786966) { | |
throw new Error(`No EXIF start tag found`); | |
} | |
// Now determine the endianness of the tags | |
// by checking the 8 byte TIFF header | |
const littleEndian = | |
dataView.getUint16(offset += 6, false) === 0x4949; | |
offset += dataView.getUint32(offset + 4, littleEndian); | |
const tags = dataView.getUint16(offset, littleEndian); | |
offset += 2; | |
for (let i = 0; i < tags; i++) { | |
const pos = offset + i * 12; | |
const tag = dataView.getUint16(pos, littleEndian); | |
if (tag === 0x0112) { // orientaion tag found | |
return dataView.getUint16(pos + 8, littleEndian); | |
} | |
} | |
} else if ((marker & 0xFF00) !== 0xFF00) { | |
break; | |
} else { | |
offset += dataView.getUint16(offset, false); | |
} | |
} | |
throw new Error(`No orientation defined`); | |
} catch (e) { | |
console.debug(e); | |
return 0; | |
} | |
} | |
function fetchAsArrayBuffer(url) { | |
return new Promise(resolve => { | |
const xhr = new XMLHttpRequest(); | |
xhr.open(`get`, url, true); | |
xhr.responseType = `arraybuffer`; | |
xhr.onreadystatechange = () => { | |
if (xhr.readyState === 4) { | |
resolve(xhr.response); | |
} | |
}; | |
xhr.onerror = () => { | |
throw new Error(`Cannot get the file`); | |
}; | |
xhr.send(); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment