Skip to content

Commit

Permalink
Merge pull request #1027 from ImageMarkup/support-exif-orientation-tag
Browse files Browse the repository at this point in the history
  • Loading branch information
danlamanna authored Nov 25, 2024
2 parents bc1cae4 + 152b425 commit 9770d19
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 0 deletions.
4 changes: 4 additions & 0 deletions isic/ingest/models/accession.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import numpy as np
from osgeo import gdal
import PIL.Image
import PIL.ImageOps
from s3_file_field import S3FileField

from isic.core.models import CopyrightLicense, CreationSortedTimeStampedModel
Expand Down Expand Up @@ -511,6 +512,9 @@ def _generate_blob(self, img: PIL.Image.Image) -> AccessionBlob:
# Any other errors are not expected, so re-raise them natively
raise

# rotate the image bytes according to the orientation tag, stripping it in the process
PIL.ImageOps.exif_transpose(img, in_place=True)

# Strip any alpha channel
if self.is_color(img):
img = img.convert("RGB")
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 32 additions & 0 deletions isic/ingest/tests/test_accession.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from django.core.exceptions import ValidationError
from django.core.files.uploadedfile import InMemoryUploadedFile
from django.urls.base import reverse
import PIL
import PIL.ExifTags
import pytest

from isic.ingest.models.accession import Accession
Expand Down Expand Up @@ -35,6 +37,36 @@ def cc_by_accession_qs(accession_factory):
return Accession.objects.filter(id=accession.id)


@pytest.mark.django_db(transaction=True)
def test_accession_orients_images(user, cohort):
name = "image_with_exif_including_orientation.jpg"
path = data_dir / name

with path.open("rb") as stream:
original_blob = InMemoryUploadedFile(stream, None, name, None, path.stat().st_size, None)

original_image = PIL.Image.open(original_blob)

assert original_image._exif.get(PIL.ExifTags.Base.Make) == "Canon"
assert original_image._exif.get(PIL.ExifTags.Base.Orientation) == 6 # 90 degrees clockwise

accession = accession_create(
creator=user,
cohort=cohort,
original_blob=original_blob,
original_blob_name=name,
original_blob_size=path.stat().st_size,
)
accession.refresh_from_db()

processed_image = PIL.Image.open(accession.blob)

# assert that all exif data is stripped but the orientation is applied
assert processed_image._exif is None
assert processed_image.height == original_image.width
assert processed_image.width == original_image.height


@pytest.mark.django_db(transaction=True)
@pytest.mark.parametrize(
("blob_path", "blob_name", "mock_as_cog"),
Expand Down

0 comments on commit 9770d19

Please sign in to comment.