Professional Development

Resize and Rotate an Image on Upload Using JavaScript

So iOS has an interesting feature when using the FileReader API that it stores an image in a default orientation irrespective of how the image is taken, so a portrait image is stored in landscape, e.g.:

CDA001-PL-0001_imageClosed

The “actual” orientation is stored in the Exif data attached to the image. This means a developer has to take an extra step to display the image with the correct orientation.

There are libraries out there to manipulate or remove Exif data (see e.g. this), but I was looking for a simple way to resize and rotate an image coming from iOS (i.e. an iPhone) without using a library. I came up with the below (see working example here). This assumes with a viewport width smaller than 400px the image needs to be rotated. It also resizes the image to 800×600 which is fine for applications that don’t need the full resolution modern iPhones provide. Of course you can do more robust checks of operating system, browser, and/or view port size.

var readURL = function(input) {
  if (input.files[0]) {
    var p = resizeMe(input.files[0]);
    p.then(function(imgBase64) {
      $('.pic').attr('src', imgBase64);
    }).catch(function(err){
      alert("error :\n" + err);
    });
  }
}

$("#getFile").on('change', function(){
  readURL(this);
});

function resizeMe(file) {
  return new Promise(function(resolve, reject) {
    var dataURL = "x";
    var reader = new FileReader();
    reader.onloadend = function () {
      var tempImg = new Image();
      tempImg.src = reader.result;
      tempImg.onload = function () {
        var MAX_WIDTH = 800;
        var MAX_HEIGHT = 600;
        var tempW = tempImg.width;
        var tempH = tempImg.height;
        if (tempW > tempH) {
          if (tempW > MAX_WIDTH) {
            tempH *= MAX_WIDTH / tempW;
            tempW = MAX_WIDTH;
          }
        } else {
          if (tempH > MAX_HEIGHT) {
            tempW *= MAX_HEIGHT / tempH;
            tempH = MAX_HEIGHT;
          }
        }

        var canvas = document.createElement('canvas');
        canvas.width = tempW;
        canvas.height = tempH;
        var ctx = canvas.getContext("2d");
        if (document.documentElement.clientWidth < 674) {
          canvas.width = tempH;
          canvas.height = tempW;
          var ctx = canvas.getContext("2d");
          ctx.translate(tempH, 0);
          ctx.rotate(90 * Math.PI / 180);
        }
        ctx.drawImage(this, 0, 0, tempW, tempH);
        dataURL = canvas.toDataURL("image/jpeg");
        resolve(dataURL);
      };
      tempImg.onerror = function(err) {
        reject("can't load the image");
      }
    };
    reader.readAsDataURL(file);
  });
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s