Nov 2nd, 2019

Fixing image orientation on mobile camera uploads

Ever run into an issue trying to fix image orientation when uploading an image that was taken with the camera on a mobile device directly Yeah, I ran into this issue this week…not fun.

After doing some research this week around the issue, I found a pretty simple solution using blueimp-load-image package. This package handles a bunch of issues related to handling images that are taken using the camera and directly uploaded to your web app.

So let’s start with understanding the issue.

The problem

The only time you run into this specific issue is when a user tries to upload a photo taken during the user experience. The story is usually:

  • User visits app
  • User clicks “upload image”
  • User selects camera on phone
  • User takes picture
  • User confirms this is the picture they want to use

If you create the image blob and set it to the source of an <img> then you get an incorrect orientation of that image.

In my case, if I took the photo vertically - then it would appear sideways on the page.

Background on the issue

TL;DR - browsers don’t handle the EXIF data provided by the phone.

For more information you can check out this excellent resources:

EXIF Orientation Handling Is a Ghetto

JS Client-Side Exif Orientation: Rotate and Mirror JPEG Images

Handle image rotation on mobile

How does blueimp-load-image address the issue

Sebastian has done an excellent job at taking the EXIF data and auto handling these scenarios for you.

For example, Orientation is figured out through the exif-map functionality here.

On top of figuring this out for you, they have provided an easy to use API.

Usage Example

First, install the package:

yarn add blueimp-load-image

Next, import the package int your JS:

import loadImage from "blueimp-load-image"

Finally, to ensure orientation is fixed:

const handleFileChange = ({ target: { files } }) => {
  const file = files.item(0)

  loadImage(
    file,
    img => {
      document.getElementById("uploaded-image").appendChild(img)
    },
    { maxWidth: 125, orientation: true }
  )
}

Note that I’m setting orientation to trueas part loadImage’s 2nd parameter object. I’ve also included a maxWidth of 125 for my use case. For more options, check out the docs here.


Alright folks, that’s all I have for today. If you found this helpful, have feedback or are interested in a quick chat - hit me up at @alvincrespo.