Skip to content

Instantly share code, notes, and snippets.

@stritti
Forked from runeb/js-exif-rotate.html
Created December 12, 2019 19:34
Show Gist options
  • Save stritti/55d9f7d587fe6e91545975a46ba9db41 to your computer and use it in GitHub Desktop.
Save stritti/55d9f7d587fe6e91545975a46ba9db41 to your computer and use it in GitHub Desktop.
Auto-rotate images locally in the browser by parsing exif data
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input id="file" type="file" accept="image/*" />
<br/>
<h2>As read:</h2>
<img id="placeholder1" width=300/><br/>
<h2>Rotated by exif data:</h2>
<img id="placeholder2" width=300/>
<script>
// Exif orientation value to css transform mapping
// Does not include flipped orientations
var rotation = {
1: 'rotate(0deg)',
3: 'rotate(180deg)',
6: 'rotate(90deg)',
8: 'rotate(270deg)'
};
function _arrayBufferToBase64( buffer ) {
var binary = ''
var bytes = new Uint8Array( buffer )
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode( bytes[ i ] )
}
return window.btoa( binary );
}
var orientation = function(file, callback) {
var fileReader = new FileReader();
fileReader.onloadend = function() {
var base64img = "data:"+file.type+";base64," + _arrayBufferToBase64(fileReader.result);
var scanner = new DataView(fileReader.result);
var idx = 0;
var value = 1; // Non-rotated is the default
if(fileReader.result.length < 2 || scanner.getUint16(idx) != 0xFFD8) {
// Not a JPEG
if(callback) {
callback(base64img, value);
}
return;
}
idx += 2;
var maxBytes = scanner.byteLength;
while(idx < maxBytes - 2) {
var uint16 = scanner.getUint16(idx);
idx += 2;
switch(uint16) {
case 0xFFE1: // Start of EXIF
var exifLength = scanner.getUint16(idx);
maxBytes = exifLength - idx;
idx += 2;
break;
case 0x0112: // Orientation tag
// Read the value, its 6 bytes further out
// See page 102 at the following URL
// http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf
value = scanner.getUint16(idx + 6, false);
maxBytes = 0; // Stop scanning
break;
}
}
if(callback) {
callback(base64img, value);
}
}
fileReader.readAsArrayBuffer(file);
};
$(function() {
$('#file').change(function() {
var file = $(this)[0].files[0];
if(file) {
orientation(file, function(base64img, value) {
$('#placeholder1').attr('src', base64img);
console.log(rotation[value]);
var rotated = $('#placeholder2').attr('src', base64img);
if(value) {
rotated.css('transform', rotation[value]);
}
});
}
});
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment