[javascript] Accessing JPEG EXIF rotation data in JavaScript on the client side

Improving / Adding more functionality to Ali's answer from earlier, I created a util method in Typescript that suited my needs for this issue. This version returns rotation in degrees that you might also need for your project.

ImageUtils.ts

/**
 * Based on StackOverflow answer: https://stackoverflow.com/a/32490603
 *
 * @param imageFile The image file to inspect
 * @param onRotationFound callback when the rotation is discovered. Will return 0 if if it fails, otherwise 0, 90, 180, or 270
 */
export function getOrientation(imageFile: File, onRotationFound: (rotationInDegrees: number) => void) {
  const reader = new FileReader();
  reader.onload = (event: ProgressEvent) => {
    if (!event.target) {
      return;
    }

    const innerFile = event.target as FileReader;
    const view = new DataView(innerFile.result as ArrayBuffer);

    if (view.getUint16(0, false) !== 0xffd8) {
      return onRotationFound(convertRotationToDegrees(-2));
    }

    const length = view.byteLength;
    let offset = 2;

    while (offset < length) {
      if (view.getUint16(offset + 2, false) <= 8) {
        return onRotationFound(convertRotationToDegrees(-1));
      }
      const marker = view.getUint16(offset, false);
      offset += 2;

      if (marker === 0xffe1) {
        if (view.getUint32((offset += 2), false) !== 0x45786966) {
          return onRotationFound(convertRotationToDegrees(-1));
        }

        const little = view.getUint16((offset += 6), false) === 0x4949;
        offset += view.getUint32(offset + 4, little);
        const tags = view.getUint16(offset, little);
        offset += 2;
        for (let i = 0; i < tags; i++) {
          if (view.getUint16(offset + i * 12, little) === 0x0112) {
            return onRotationFound(convertRotationToDegrees(view.getUint16(offset + i * 12 + 8, little)));
          }
        }
        // tslint:disable-next-line:no-bitwise
      } else if ((marker & 0xff00) !== 0xff00) {
        break;
      } else {
        offset += view.getUint16(offset, false);
      }
    }
    return onRotationFound(convertRotationToDegrees(-1));
  };
  reader.readAsArrayBuffer(imageFile);
}

/**
 * Based off snippet here: https://github.com/mosch/react-avatar-editor/issues/123#issuecomment-354896008
 * @param rotation converts the int into a degrees rotation.
 */
function convertRotationToDegrees(rotation: number): number {
  let rotationInDegrees = 0;
  switch (rotation) {
    case 8:
      rotationInDegrees = 270;
      break;
    case 6:
      rotationInDegrees = 90;
      break;
    case 3:
      rotationInDegrees = 180;
      break;
    default:
      rotationInDegrees = 0;
  }
  return rotationInDegrees;
}

Usage:

import { getOrientation } from './ImageUtils';
...
onDrop = (pics: any) => {
  getOrientation(pics[0], rotationInDegrees => {
    this.setState({ image: pics[0], rotate: rotationInDegrees });
  });
};

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to jpeg

Image steganography that could survive jpeg compression How do I insert a JPEG image into a python Tkinter window? JPG vs. JPEG image formats C# Base64 String to JPEG Image Changing all files' extensions in a folder with one command on Windows Convert RGBA PNG to RGB with PIL Converting a byte array to PNG/JPG Python Image Library fails with message "decoder JPEG not available" - PIL matplotlib savefig in jpeg format Accessing JPEG EXIF rotation data in JavaScript on the client side

Examples related to exif

JS Client-Side Exif Orientation: Rotate and Mirror JPEG Images Accessing JPEG EXIF rotation data in JavaScript on the client side In Python, how do I read the exif data for an image? How to get the EXIF data from a file using C#

Examples related to html5-canvas

Scaling an image to fit on canvas Tainted canvases may not be exported How to fix getImageData() error The canvas has been tainted by cross-origin data? JS Client-Side Exif Orientation: Rotate and Mirror JPEG Images Resize image with javascript canvas (smoothly) How to show a running progress bar while page is loading HTML5 Canvas Resize (Downscale) Image High Quality? HTML5 Canvas Rotate Image Real mouse position in canvas Changing three.js background to transparent or other color