Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent images from being rotated if the original contains EXIF orientation metadata #93

Closed
wants to merge 1 commit into from

Conversation

alanpreed
Copy link

Fixes: #49

Adds a rotation operation using sharp immediately prior to resizing, as suggested in Stack Overflow post here.

@jacob
Copy link

jacob commented May 8, 2021

This looks good based on the Stack Overflow post you mention. One thing that would make this PR stronger is if we add an image to the test directory that exhibits the issue and is not square. Then a similar test to https://github.com/11ty/eleventy-img/blob/master/test/test.js#L233 -- "Try to use a width larger than original (statsSync)" could demonstrate whether the bug is fixed by checking that the width is longer than the length (or vice versa depending on the test image).

The only difficulty is that a test image should be small, an original file from an iPhone would be too large to be good for testing. Perhaps the person who reported issue #49 could help in generating a small image file which has EXIF data that exhibits the bug.

@alanpreed
Copy link
Author

Below are a couple of images that I have created for testing. The first has no EXIF header, and the second has the following minimal EXIF data that should set the orientation to be upside down:

$ exiv2 -pt orientation_image.jpg 
Exif.Image.Orientation                       Short       1  bottom, right
Exif.Image.DateTime                          Ascii      20  2021:05:10 20:51:53
Exif.Image.ExifTag                           Long        1  70
Exif.Photo.DateTimeOriginal                  Ascii      20  2021:05:10 20:51:53
Exif.Thumbnail.JPEGInterchangeFormat         Long        1  138
Exif.Thumbnail.JPEGInterchangeFormatLength   Long        1  0

orientation_image_noexif

orientation_image

Although the images display with their correct orientation here, in my file browser, and when opened in Firefox, unfortunately it appears that sharp ignores their metadata completely.

This issue is not limited to using the rotate function either. I tried adding sharpInstance.withMetadata(); prior to sharpInstance.resize(resizeOptions);, and found that sharp will not copy over the metadata from these images . The camera image that I originally encountered the rotation issue with does have its metadata transferred correctly when this line is added.

Presumably something is missing from my metadata, although I did try copying all fields over from the camera image and it was still ignored. I can't see anything obvious within sharp's documentation or sourcecode to point me to what might be missing, nor can I see a way to produce verbose output from sharp to work out where things are going wrong internally, so I'm not sure what to try at this point I'm afraid,

@hnrklssn
Copy link

This doesn't seem to work when keeping the original resolution: if I pass widths: [600, null] the resized version of my image is rotated correctly, while the original resolution output is unrotated but without the EXIF data to indicate orientation.

@@ -292,6 +292,7 @@ async function resizeImage(src, options = {}) {
if(metadata.format !== "svg" || !options.svgAllowUpscale) {
resizeOptions.withoutEnlargement = true;
}
sharpInstance.rotate();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is never reached if stat.width < metadata.width || (options.svgAllowUpscale && metadata.format === "svg" is false.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's OK. The issue is caused when resizing only, so the code is reached for the same cases when the bug is happening.

@hnrklssn
Copy link

If the image is rotated 90 or 270 degrees getValidWidths will return what will be the height as the "width" for falsy values in the widths array, since that is the width of the input image.

@zachleat
Copy link
Member

This seems okay to me but needs another stat.width === metadata.width && metadata.format !== "svg" branch in there I think—to handle the original image width too.

Copy link

@jdvivar jdvivar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@zachleat
Copy link
Member

Closing for #132

@zachleat zachleat closed this Feb 23, 2022
@zachleat zachleat added this to the v1.0.1 milestone Feb 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Resized images are rotated if original image contains EXIF orientation metadata
5 participants