Guide
Why your uploaded photos appear sideways (EXIF orientation)
How cameras store rotation in EXIF metadata, why images still show up rotated, and how to handle all eight orientations correctly.
A phone camera sensor always captures in the same direction. When you hold the phone upright, the camera doesn’t rotate the pixels. It saves them as they came off the sensor and writes an Orientation tag into the file’s EXIF metadata saying how the image should be turned for display.
If your code reads the pixels but ignores that tag, the photo appears sideways or upside down. This usually happens when a server resizes an image and strips the metadata along the way.
The eight orientations
The tag has eight values: the four rotations, each with or without a mirror flip.
| Value | Transform needed to display |
|---|---|
| 1 | None (normal) |
| 2 | Flip horizontally |
| 3 | Rotate 180° |
| 4 | Flip vertically |
| 5 | Transpose (flip across the top-left → bottom-right diagonal) |
| 6 | Rotate 90° clockwise — most portrait phone photos |
| 7 | Transverse (flip across the other diagonal) |
| 8 | Rotate 90° counter-clockwise |
We have one sample file for each value. Every file stores its pixels transformed and sets the matching tag, so a correct implementation shows an upright F with “This side up” at the top for all eight. A broken one shows it rotated or mirrored.
- Orientation 6 (the common phone case)
- Orientation 3
- Orientation 5 (mirrored — the one most often missed)
How to handle it
Browsers: modern browsers apply EXIF orientation to <img> automatically (the CSS default is image-orientation: from-image). Problems usually come from your own processing, not the browser.
Servers: apply the rotation to the pixels, then remove or reset the tag, before resizing or stripping metadata:
- ImageMagick:
magick in.jpg -auto-orient out.jpg - Pillow:
ImageOps.exif_transpose(img) - sharp (Node.js):
sharp(input).rotate()— callingrotate()with no arguments auto-orients - libvips:
vips autorot in.jpg out.jpg
Canvas: createImageBitmap(blob, { imageOrientation: 'from-image' }) returns correctly oriented pixels for client-side resizing.
Test with all eight files, not only orientation 6. Mirrored orientations (2, 4, 5, 7) are rare from phones but common from scanners and some webcams.