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

exif_transpose overwrites the original image exif #5546

Closed
artemisart opened this issue Jun 18, 2021 · 1 comment · Fixed by #5547
Closed

exif_transpose overwrites the original image exif #5546

artemisart opened this issue Jun 18, 2021 · 1 comment · Fixed by #5547
Labels
Bug Any unexpected behavior, until confirmed feature. Exif

Comments

@artemisart
Copy link

artemisart commented Jun 18, 2021

What did you do?

Use ImageOps.exif_tranpose on an image with an EXIF orientation code (not in [None, 0, 1]).

What did you expect to happen?

exif_transpose() should be immutable and returns a new image with the correct orientation.

What actually happened?

exif_transpose() returns a new image but also modifies the original image exif info in-place (deletes the orientation, key 0x112).
It's a pretty big problem if your work with rotated images because it breaks the original images, if you e.g. call again exif_transpose() on it the EXIF orientation value is not there but the image content is not correctly rotated.

What are your OS, Python and Pillow versions?

  • OS: ubuntu 18.04
  • Python: 3.8.8
  • Pillow: 8.2.0

Code

import PIL, PIL.ImageOps
# if you have an image with exif
pil = PIL.Image.open(file)
# otherwise
import requests
resp = requests.get('https://raw.githubusercontent.com/recurser/exif-orientation-examples/master/Portrait_3.jpg', stream=True)
resp.raw.decode_content = True
pil = PIL.Image.open(resp.raw)

print(pil.getexif().get(0x0112))  # 3
correct_image = PIL.ImageOps.exif_transpose(pil)
print(pil.getexif().get(0x0112))  # None, but should be 3

Proposed fix

Replace the first line of exif_tranpose in https://pillow.readthedocs.io/en/stable/_modules/PIL/ImageOps.html#exif_transpose with

from copy import deepcopy  # copy may be enough, I didn't try it

-    exif = image.getexif()
+    exif = deepcopy(image.getexif())
@radarhere radarhere changed the title Bug: exif_tranpose overwrites the original image exif Bug: exif_transpose overwrites the original image exif Jun 18, 2021
@artemisart artemisart changed the title Bug: exif_transpose overwrites the original image exif Bug: exif_transpose overwrites the original image exif Jun 18, 2021
@radarhere radarhere added the Exif label Jun 18, 2021
@radarhere
Copy link
Member

Yep, good point. I've created PR #5547 to resolve this - my method was not to copy the Image.Exif instance of the original image, but to create a new instance from the output image.

@radarhere radarhere added the Bug Any unexpected behavior, until confirmed feature. label Jun 18, 2021
@radarhere radarhere changed the title Bug: exif_transpose overwrites the original image exif exif_transpose overwrites the original image exif Jun 18, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Any unexpected behavior, until confirmed feature. Exif
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants