Skip to content

Instantly share code, notes, and snippets.

@nezed
Created August 21, 2016 23:54
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save nezed/d536ccdace84c6f2ef13da47a8fd6bdb to your computer and use it in GitHub Desktop.
Save nezed/d536ccdace84c6f2ef13da47a8fd6bdb to your computer and use it in GitHub Desktop.
EXIF image orientation CSS transform fix / fix orientation of image picked from local FS without canvas
/*
* This gist will help you to fix orientation
* of image picked from local FS
* without canvas.
* CSS-only!
*
* @expample
* const img = document.createElement('img')
* img.src = URL.createObjectURL(file)
* img.style.transform = ORIENT_TRANSFORMS[ getOrientation(file) ]
*/
const ORIENT_TRANSFORMS = {
1: '',
2: 'rotateY(180deg)',
3: 'rotate(180deg)',
4: 'rotate(180deg) rotateY(180deg)',
5: 'rotate(270deg) rotateY(180deg)',
6: 'rotate(90deg)',
7: 'rotate(90deg) rotateY(180deg)',
8: 'rotate(270deg)'
}
/*
* http://stackoverflow.com/a/32490603
*/
function getOrientation( file ) {
return new Promise( ( resolve, reject ) => {
const reader = new FileReader();
reader.onerror = reject
reader.onload = ( { target } ) => {
try {
const view = new DataView( target.result ),
length = view.byteLength
let offset = 2
if( view.getUint16(0, false) != 0xFFD8 ) {
return reject( new Error( 'File is not a .jpeg' ) )
}
while( offset < length ) {
const marker = view.getUint16( offset, false )
offset += 2;
if (marker == 0xFFE1) {
if( view.getUint32( offset += 2, false ) != 0x45786966 ) {
return resolve()
}
const little = view.getUint16(offset += 6, false) == 0x4949
offset += view.getUint32(offset + 4, little)
const tags = view.getUint16(offset, little)
offset += 2
for( var i = 0; i < tags; i++ ) {
if( view.getUint16( offset + ( i * 12 ), little ) == 0x0112 ) {
return resolve( view.getUint16( offset + ( i * 12 ) + 8, little ) )
}
}
} else if( ( marker & 0xFF00 ) != 0xFF00 ) {
break;
} else {
offset += view.getUint16( offset, false )
}
}
return resolve()
} catch( err ) {
return reject( err )
}
};
reader.readAsArrayBuffer( file.slice( 0, 64 * 1024 ) );
} )
}
@z-vr
Copy link

z-vr commented Jan 6, 2017

Cool thanks, although it does not keep the image aligned to the top left corner.
See http://stackoverflow.com/questions/18531698/css-rotate-image-and-align-top-left

@z-vr
Copy link

z-vr commented Jan 6, 2017

@nezed
Copy link
Author

nezed commented Jan 25, 2017

@z-vr Thanks for idea about transfrom-origin fix for non-square images.
And also its nice to know that this snippet inspired you to build your own solution!

@vdavid
Copy link

vdavid commented Apr 10, 2020

Thanks a lot for this gist @nezed! I used parts of your code for my class-based version, wrapped in an ES6 module. I think this might spare some time for people to add it in their projects. Here you go: https://gist.github.com/vdavid/3f9b66b60f52204317a4cc0e77097913

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment