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

AVIF image saved with incorrect EXIF orientation metadata after calling auto_orient #137

Closed
Stormheg opened this issue Nov 19, 2023 · 2 comments · Fixed by #136
Closed
Labels

Comments

@Stormheg
Copy link
Member

When calling the auto_orient() method on a JPEG image with EXIF orientation metadata, the resulting image has the orientation applied directly to the image data. This works as expected.

But if the image is then saved using save_as_avif(), the (now incorrect) EXIF orientation metadata is encoded into the resulting AVIF file as well. This incorrectly tells viewers to rotate the image, resulting in a end user seeing a rotated image.

Steps to reproduce

  1. Create a new Django project: django-admin startproject willow_avif_issue
  2. Download and unzip image.jpeg.zip in the root of the django project created in the previous step. The extracted image.jpeg has EXIF orientation metadata. Here's a screenshot of the orientation metadata from macOS Preview:
image
  1. Install Willow with AVIF support in your Django project: pip install willow[heif]
  2. Create a new management command (touch willow_avif_issue/management/commands/test_willow.py) with the following contents. Willow will throw an error if it is not being called from inside a configured Django project.
# willow_avif_issue/management/commands/test_willow.py
from django.core.management.base import BaseCommand
from willow.image import Image


class Command(BaseCommand):
    help = 'Test willow'

    def handle(self, *args, **options):
        with open('./image.jpeg', 'rb') as f:
            img = Image.open(f)

            img = img.auto_orient()
            img.save_as_avif('image.avif')
  1. Run the management command: python manage.py test_willow

  2. The resulting image.avif created in the project root should have the EXIF orientation directly applied to the image data. This can be verified by viewing the width and height. The image.avif also retains the same EXIF orientation metadata. This tells viewers to rotate the image (again), resulting in a rotated image:

image

Expected outcome

The EXIF orientation metadata is no longer correct and should probably be removed.

Notes

This specifically affects saving as AVIF. When saving as JPEG, it appears EXIF metadata is being (mostly) stripped. Other formats don't support orientation metadata at all I believe.

Technical details

  • Python version: 3.11.6
  • pip freeze output
asgiref==3.7.2
defusedxml==0.7.1
Django==4.2.7
filetype==1.2.0
Pillow==10.1.0
pillow-heif==0.13.1
sqlparse==0.4.4
Willow==1.6.2
@Stormheg Stormheg added the bug label Nov 19, 2023
Stormheg added a commit that referenced this issue Nov 19, 2023
Move away from bespoke logic and rely on `ImageOps.exif_transpose()`.
This method works much better than our own as it also supports reading
XMP metadata instead of just EXIF.

In addition, it also removes the orientation metadata from the transposed image.

This method was added in Pillow 6.0.0.
See: https://github.com/python-pillow/Pillow/blob/28c173f8d4767c7f6dd22dc840117fe641f4d3ee/docs/releasenotes/6.0.0.rst#added-imageopsexif_transpose

This fixes #137 in the process by removing stale orientation metadata.
@robmoorman
Copy link
Member

If more input is needed please ask. We (Storm and I) have several use-cases now were this goes wrong in willow.

@zerolab
Copy link
Collaborator

zerolab commented Nov 21, 2023

This will be fixed by #136 which is on my list for this week. Will do my best to get to it ASAP

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
3 participants