PrepShot Open the app

Blog

Why iPhone photos arrive sideways, and whose fault it is

You shoot a product in portrait. It looks right on the phone, right in Finder, right in the preview. You upload it and it is on its side.

This is one of the most common problems in e-commerce photography and it has an unusually precise cause.

Photographs are not stored the way you see them

A camera sensor is a fixed rectangle. It does not rotate when you turn the camera. What happens instead is that the camera records which way up it was and stores that alongside the pixels, leaving whoever displays the image to apply it.

In JPEG this is the EXIF Orientation tag, a number from 1 to 8. In the HEIC files an iPhone actually writes, it is usually something different: a rotation property inside the file's container, called irot.

So an upright-looking photo is often a sideways rectangle plus an instruction. Software that reads the instruction shows it correctly. Software that ignores it does not.

Where it goes wrong

Three separate failures produce the same symptom.

The tag is ignored. Older uploaders and bulk-import tools sometimes read raw pixels and skip the metadata. The image goes up rotated.

The tag is stripped. Many pipelines remove metadata to reduce file size: a reasonable thing to do, since EXIF can carry your location. If the pixels are not rotated before the tag is removed, the only record of which way up the photo goes is deleted.

The tag is applied twice. This one is the most interesting. If a decoder has already straightened the image using the container's rotation, and then something applies the EXIF tag on top, the photograph is rotated a second time. It arrives at 180 degrees, or on the wrong side.

The double-rotation trap, in detail

We hit this building our own decoder and it is worth being specific, because it is a trap anyone processing HEIC will meet.

The library most tools use for HEIC is libheif. Reading its source rather than guessing: its decoding options default ignore_transformations to false, and the decode path then walks the image's properties applying rotate_ccw() for any irot box and mirror_inplace() for any imir box.

In other words, libheif straightens the image itself. If you then apply the EXIF Orientation tag as well, you rotate twice.

But you cannot simply ignore EXIF either, because that leaves a narrow case broken: a HEIC whose rotation lives only in EXIF, with no irot box. Apple writes irot, but nothing obliges other encoders to.

The correct behaviour is to check which of the two the file actually carries, and apply exactly one of them.

Why HEIC makes it worse

JPEG has one place to store rotation: the EXIF Orientation tag. HEIC has two, and that is the whole problem.

HEIC is not really an image format. It is a container, based on the same box structure as MP4 video. Inside it, an image can carry transformation properties: irot for rotation and imir for mirroring. These are structural parts of the file, not metadata.

But a HEIC can also carry an EXIF block, because it inherited that from the world it came from.

So a rotated iPhone photograph can describe its rotation twice, in two independent places, using two different conventions. Software that reads one and ignores the other is correct. Software that reads both and applies both rotates twice. Software that reads only EXIF, on a file that has only irot, does not rotate at all.

All three behaviours exist in shipping software today.

The eight orientation values

EXIF Orientation is not a rotation in degrees. It is a number from 1 to 8 describing both rotation and mirroring:

ValueMeaning
1Normal, no transformation
2Mirrored horizontally
3Rotated 180 degrees
4Mirrored vertically
5Mirrored horizontally and rotated 270 degrees clockwise
6Rotated 90 degrees clockwise
7Mirrored horizontally and rotated 90 degrees clockwise
8Rotated 270 degrees clockwise

Values 1, 3, 6 and 8 are the common ones from a camera held four ways. The mirrored values mostly come from front-facing cameras and scanners.

Note that values 5 to 8 swap the image's width and height. A pipeline that reads the dimensions before applying orientation and allocates a canvas from them produces a portrait photograph squeezed into a landscape frame: a distinct and quite common failure that looks different from a simple rotation.

Where the tag gets lost

Even a correctly-tagged file can arrive rotated, because the tag is fragile in transit.

Messaging apps. Sending a photograph through most messaging services re-encodes it, and several strip metadata in the process. Some rotate the pixels first; some do not. A photograph that looked right on the phone can arrive at your desktop on its side, and the sender did nothing wrong.

Cloud sync. Uploading to one service and downloading from another can pass through two re-encodes. Each is an opportunity to lose the tag.

Email. Some clients re-encode attachments to reduce size.

Marketplaces themselves. Most strip metadata on upload as a matter of course, which is generally good for your privacy. It also means any rotation still living in the tag is discarded, and the pixels are whatever they were.

That last point is the practical one. Because the marketplace strips the tag, the rotation must be in the pixels before you upload. A file that relies on the tag is relying on something that will not survive.

How to check a file yourself

On macOS or Linux, if you have ExifTool installed:

exiftool -Orientation -n photo.jpg

The -n gives you the raw number rather than a description. On any platform, most photo viewers show it under file information, though many describe it in words rather than the value.

The more useful test is empirical. Take one product, photograph it four times with the phone held normally, upside down, and rotated each way. Run all four through your process. If any arrives wrong, you have found the bug before a customer did, and you have found which of the eight values your pipeline mishandles, which narrows the cause considerably.

What a correct implementation does

The logic is short enough to state completely:

  1. Decode the image, telling the decoder not to apply orientation itself if it offers that option.
  2. Inspect the file for a container rotation property. In HEIC, that means looking for an irot box.
  3. If one exists, the decoder has probably already applied it, so do not apply EXIF on top.
  4. If none exists, read the EXIF Orientation tag and apply it.
  5. Bake the result into the pixels.
  6. Only then strip metadata.

Step 1 is the one most often missed, and the consequence is the double rotation. Browsers accept an imageOrientation option on image decoding for exactly this reason, and a pipeline that assumes the decoder leaves the tag alone, without checking, is relying on behaviour that varies.

Step 6 matters because stripping metadata before applying it destroys the only record of which way up the photograph goes.

The width-and-height trap

A separate failure with the same symptom, and worth calling out because it looks like a rotation bug and is not.

Orientation values 5 through 8 swap the image's width and height. A pipeline that reads the dimensions from the file header, allocates a canvas of that size, and then applies a 90-degree rotation ends up drawing a portrait image into a landscape frame.

The result is not a rotated photograph. It is a squashed or cropped one. If your output looks stretched rather than turned, this is the cause, and it is fixed by computing the output dimensions after deciding the orientation rather than before.

What to do about it

Test all four orientations, not one. Shoot the same product held four ways and run all four through your process. Orientation bugs are famously asymmetric: a pipeline can be right for portrait and wrong for upside-down portrait.

Straighten before stripping metadata. If your tool removes EXIF, make sure the rotation is baked into the pixels first. Once the tag is gone it cannot be recovered.

Be suspicious of anything that says it "supports HEIC". Support ranges from "decodes the pixels" to "handles rotation, mirroring, colour profiles and multi-image containers correctly". The first is common and the second is not.

We wrote about the general shape of this because it costs sellers real time, and because the answer is genuinely non-obvious: the two places a rotation can live look identical from the outside, and applying both is worse than applying neither.