fix image orientation
This commit is contained in:
+4
-2
@@ -6,7 +6,7 @@ import subprocess
|
||||
from tempfile import TemporaryDirectory
|
||||
|
||||
from fastapi import HTTPException, UploadFile
|
||||
from PIL import Image, UnidentifiedImageError
|
||||
from PIL import Image, ImageOps, UnidentifiedImageError
|
||||
|
||||
try:
|
||||
from pillow_heif import register_heif_opener
|
||||
@@ -59,7 +59,9 @@ def process_upload(file: UploadFile | None) -> ProcessedImage | None:
|
||||
|
||||
|
||||
def _prepare_image(source_image: Image.Image) -> ProcessedImage:
|
||||
prepared = _strip_metadata_and_convert(source_image)
|
||||
# Normalize orientation from EXIF before resizing or stripping metadata.
|
||||
prepared = ImageOps.exif_transpose(source_image)
|
||||
prepared = _strip_metadata_and_convert(prepared)
|
||||
prepared.thumbnail((MAX_IMAGE_SIDE, MAX_IMAGE_SIDE))
|
||||
|
||||
output = BytesIO()
|
||||
|
||||
@@ -63,6 +63,19 @@ def make_image_upload(
|
||||
return (filename, output.getvalue(), "image/png")
|
||||
|
||||
|
||||
def make_oriented_jpeg_upload(
|
||||
filename="portrait.jpg",
|
||||
size=(1600, 900),
|
||||
orientation=6,
|
||||
):
|
||||
image = Image.new("RGB", size, (20, 120, 220))
|
||||
exif = Image.Exif()
|
||||
exif[274] = orientation
|
||||
output = BytesIO()
|
||||
image.save(output, format="JPEG", exif=exif)
|
||||
return (filename, output.getvalue(), "image/jpeg")
|
||||
|
||||
|
||||
def read_jpeg_size(image_bytes):
|
||||
with Image.open(BytesIO(image_bytes)) as image:
|
||||
return image.format, image.size
|
||||
@@ -357,6 +370,21 @@ def test_can_upload_image_for_box_and_process_it(client, db_session):
|
||||
assert image_size == (1600, 800)
|
||||
|
||||
|
||||
def test_image_pipeline_applies_exif_orientation_before_saving(client, db_session):
|
||||
response = create_box(client, name="Portrait Box", image=make_oriented_jpeg_upload())
|
||||
|
||||
assert response.status_code == 303
|
||||
|
||||
box = db_session.query(Box).filter_by(name="Portrait Box").one()
|
||||
assert box.image_blob is not None
|
||||
assert box.image_width == 900
|
||||
assert box.image_height == 1600
|
||||
|
||||
image_format, image_size = read_jpeg_size(box.image_blob)
|
||||
assert image_format == "JPEG"
|
||||
assert image_size == (900, 1600)
|
||||
|
||||
|
||||
def test_can_upload_image_for_item(client, db_session):
|
||||
box = Box(name="Main Box")
|
||||
db_session.add(box)
|
||||
|
||||
Reference in New Issue
Block a user