blueimp / JavaScript-Load-Image

Load images provided as File or Blob objects or via URL. Retrieve an optionally scaled, cropped or rotated HTML img or canvas element. Use methods to parse image metadata to extract IPTC and Exif tags as well as embedded thumbnail images, to overwrite the Exif Orientation value and to restore the complete image header after resizing.
https://blueimp.github.io/JavaScript-Load-Image/
MIT License
4.46k stars 923 forks source link

Width and height are swapped. Sample image. #116

Closed Edd-C closed 4 years ago

Edd-C commented 4 years ago

Hello,

When I upload an image taken on an iPhone XS at a fairly high res, the exif data show the heigth and width swapped.

Here is the sample image I'm using: IMG_0638

Details: image

When I use your demo tool here to upload that image, I get this (notice the swapped x and y vals):

Settings: image

Exif

ExposureTime | 0.025 FNumber | 1.8 ExposureProgram | Normal program PhotographicSensitivity | 320 ExifVersion | 0231 DateTimeOriginal | 2020:06:18 13:58:10 DateTimeDigitized | 2020:06:18 13:58:10 OffsetTime | -07:00 OffsetTimeOriginal | -07:00 OffsetTimeDigitized | -07:00 ComponentsConfiguration | YCbCr ShutterSpeedValue | 5.322043519394513 ApertureValue | 1.6959938128383605 BrightnessValue | 1.1605250820440693 ExposureBias | 0 MeteringMode | Pattern Flash | Flash did not fire, compulsory flash mode FocalLength | 4.25 SubjectArea | 2015,1511,2323,1393 SubSecTimeOriginal | 155 SubSecTimeDigitized | 155 FlashpixVersion | 0100 ColorSpace | 65535 PixelXDimension | 4032 PixelYDimension | 3024 SensingMethod | One-chip color area sensor SceneType | Directly photographed ExposureMode | 0 WhiteBalance | Auto white balance FocalLengthIn35mmFilm | 26 SceneCaptureType | Standard LensSpecification | 4.25,6,1.8,2.4 LensMake | Apple LensModel | iPhone XS back dual camera 4.25mm f/1.8

TIFF

Make | Apple Model | iPhone XS Orientation | Rotate 90° CW XResolution | 72 YResolution | 72 ResolutionUnit | 2 Software | 13.5.1 DateTime | 2020:06:18 13:58:10 YCbCrPositioning | 1

Is there a setting I'm missing? Or is this a bug?

var loadingImage = loadImage(
    e.target.files[0],
    function(img, meta) {
        var x = img.toDataURL('image/jpeg');
        var y = dataURLToBlob(x);
        document.getElementById('preview').src = x;

        // Trigger custom event.
        $.event.trigger({
            type: 'imageResized',
            blob: y,
            url: x,
                        exif: meta
        });
    },
    {
        meta: true,
        canvas: true,
        orientation: true,
        contain: true,
        maxWidth: 1000,
        maxHeight: 1000
    }
);
blueimp commented 4 years ago

The Exif data contains the original pixel dimensions. So if you rotate the image on client-side (e.g. with orientation: true), the pixel data might be swapped, but the Exif dimensions will retain their original values.

So far this library only supports to override the Exif orientation value: https://github.com/blueimp/JavaScript-Load-Image#exif-writer

Technically, the writeExifData method could write Exif data at all Exif offset positions, but it's only easy to do so with values that have the same byte length, since otherwise you would have to change the Exif tag length and possibly update all following Exif offset positions.

That's why only the Orientation writer has been implemented so far, but it is set up to be extended:

https://github.com/blueimp/JavaScript-Load-Image/blob/af40950cd629651a249a6639033fe28c6b968ac7/js/load-image-exif.js#L432-L441

PS: Instead of doing canvas.toDataURL and dataURLToBlob, it will be more efficient to use canvas.toBlob() to create the Blob and URL.createObjectURL(blob) to create the URL (if you need the URL only client-side).

Edd-C commented 4 years ago

So if you rotate the image on client-side (e.g. with orientation: true), the pixel data might be swapped, but the Exif dimensions will retain their original values.

Are you suggesting that the meta function(img, meta) { should contain the original photo dimensions?

When logged, they are swapped.

Capture Capture1 Capture3

Is there another way to grab the correct Original dimensions?

Edd-C commented 4 years ago

Also, this is only happening with some (not all) images for us. I have yet to identify the cause.

blueimp commented 4 years ago

The Exif Pixel dimensions represent the original pixel data as taken by the camera, which are not necessarily the same dimensions as the image in its correct orientation.

For example, the following is the letter F with the Exif orientation value 6:

██
██  ██
██████████

Correctly oriented, the width and height dimensions will be swapped:

██████
██
████
██
██

That means the Exif Pixel dimensions for a picture with Exif orientation values 5, 6, 7 and 8 will always be swapped compared to the correctly orientated image.

This has nothing to do with this library and you can test this yourself by analyzing the Exif data of any picture taken with an Exif orientation value in this range.

Edd-C commented 4 years ago

Thank you for your patience. I see the correlation between orientation and the width/height now. I was able to solve it.

Kind regards.