blueimp/JavaScript-Load-Image

Width and height are swapped. Sample image.

Edd-C opened this issue · 5 comments

Edd-C commented

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
	}
);

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:

loadImage.exifWriters = {
// Orientation writer:
0x0112: function (buffer, data, value) {
var orientationOffset = data.exifOffsets[0x0112]
if (!orientationOffset) return buffer
var view = new DataView(buffer, orientationOffset + 8, 2)
view.setUint16(0, value, data.exifLittleEndian)
return buffer
}
}

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

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

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

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

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

Kind regards.