Rotate and reflect images, as specified in EXIF whilst uploading

This commit is contained in:
Martin Green 2023-07-13 12:34:52 +02:00
parent c119c99308
commit bdb5e3208b

View File

@ -9,6 +9,8 @@ from django.urls import reverse
from django.views.decorators.csrf import ensure_csrf_cookie from django.views.decorators.csrf import ensure_csrf_cookie
from PIL import Image from PIL import Image
import piexif
import troggle.settings as settings import troggle.settings as settings
from troggle.core.utils import WriteAndCommitError, write_and_commit from troggle.core.utils import WriteAndCommitError, write_and_commit
@ -52,6 +54,27 @@ def image_selector(request, path):
thumbnails.append({"thumbnail_url": thumbnail_url, "page_url": page_url}) thumbnails.append({"thumbnail_url": thumbnail_url, "page_url": page_url})
return render(request, "image_selector.html", {"thumbnails": thumbnails}) return render(request, "image_selector.html", {"thumbnails": thumbnails})
def reorient_image(img, exif_dict):
if piexif.ImageIFD.Orientation in exif_dict["0th"]:
print(exif_dict)
orientation = exif_dict["0th"].pop(piexif.ImageIFD.Orientation)
if orientation == 2:
img = img.transpose(Image.FLIP_LEFT_RIGHT)
elif orientation == 3:
img = img.rotate(180)
elif orientation == 4:
img = img.rotate(180).transpose(Image.FLIP_LEFT_RIGHT)
elif orientation == 5:
img = img.rotate(-90, expand=True).transpose(Image.FLIP_LEFT_RIGHT)
elif orientation == 6:
img = img.rotate(-90, expand=True)
elif orientation == 7:
img = img.rotate(90, expand=True).transpose(Image.FLIP_LEFT_RIGHT)
elif orientation == 8:
img = img.rotate(90, expand=True)
return img
@login_required_if_public @login_required_if_public
@ -67,6 +90,14 @@ def new_image_form(request, path):
for chunk in f.chunks(): for chunk in f.chunks():
binary_data.write(chunk) binary_data.write(chunk)
i = Image.open(binary_data) i = Image.open(binary_data)
if "exif" in i.info:
exif_dict = piexif.load(i.info["exif"])
i = reorient_image(i, exif_dict)
exif_dict['Exif'][41729] = b'1'
exif = piexif.dump(exif_dict)
else:
exif = None
width, height = i.size width, height = i.size
if width > MAX_IMAGE_WIDTH or height > MAX_IMAGE_HEIGHT: if width > MAX_IMAGE_WIDTH or height > MAX_IMAGE_HEIGHT:
scale = max(width / MAX_IMAGE_WIDTH, height / MAX_IMAGE_HEIGHT) scale = max(width / MAX_IMAGE_WIDTH, height / MAX_IMAGE_HEIGHT)