blueimp/JavaScript-Load-Image

originalWidth and originalHeight values not the same over all browsers

loekup opened this issue · 4 comments

When reading the originalWidth and originalHeight for a rotated image on firefox or safari the values still reflect the image before rotation

On Chrome the width and height are reflecting the image after rotation

When checking the code i found that Firefox and Safari would never hit the following lines of code

if (data) {
var autoOrientation =
loadImage.orientation && data.exif && data.exif.get('Orientation')
if (autoOrientation > 4 && autoOrientation < 9) {
// Automatic image orientation switched image dimensions
var originalWidth = data.originalWidth
var originalHeight = data.originalHeight
data.originalWidth = originalHeight
data.originalHeight = originalWidth
}
}
callback(img, data)
},

Is never hit because loadImage.orientation is always false for FF and Safari even if the options.orientation is true;

So the images are rotated properly for all browsers
But the values in originalWidth and originalHeight are not all the same for all browsers

Hi @loekup,

Automatic image orientation support is inconsistent even between modern browsers, see e.g. this test page.

After discussion on issue #97, I've implemented normalization of the original dimensions, however that requires parsing of image meta data to retrieve the Exif Orientation value.

You can enable this behavior by setting the option meta: true.

When image meta data parsing is enabled, behavior is consistent, see e.g. the unit test for original image dimensions.

Please let me know if you get a failing result on this unit test, otherwise we can likely close this issue (although this might be a case for better documentation).

When using meta: true and orientation: true the bug returns the other way around
Safari and firefox return the right width and height value, but chrome does not

On all browsers the actual image returned is right, only the values of originalWidth and originalHeight are inconsistent

I can try to reproduce the issue on a smaller scale (currently its pretty baked in our projects source code)

I think i spoke a bit too soon, just tested it with meta: true and orientation: true i now get consistent values over all browsers, only the values i'm getting are the values from before rotation

For example: i am rotating a 800x600 image with exif Orientation: 5 after rotation i am expecting originalWidth: 600 originalHeight: 800 but i am recieving originalWidth: 800 originalHeight: 600

For now my option is to read the exif rotation on our side and flip the width and height values if the orientation is between exif orientation 4 and 9

Yes, the idea of originalWidth and originalHeight is to show the original dimensions before rotation.

If it would be after rotation we would have to accept inconsistent values between browsers (see the aforementioned issue discussion).

So originalWidth and originalHeight are basically equivalent with the Exif values PixelXDimension and PixelYDimension, as they show the original dimensions of the pixel data.

If you want to know the dimensions of an auto-oriented image after orientation, you could load the image with orientation: true, but no other options set and then do any scaling operations afterward:

loadImage(e.target.files[0], { orientation: true }).then(function (data) {
  var image = data.image
  console.log(image.width, image.height)
  var scaledImage = loadImage.scale(image, { maxWidth: 600 })
  // ...
})

There are no performance penalties for doing it this way, as this is what loadImage does internally as well.

See also this post for the current browser support for auto-orientation (e.g. Safari 13 does support auto-orientation) and why it cannot be disabled for Out-of-DOM operations.

I'm gonna close this issue as the library behavior is consistent, but feel free to add further comments.