mirror of
https://github.com/pretix/pretix.git
synced 2026-05-09 15:54:03 +00:00
Thumbnails: Support animated GIFs (#2686)
Co-authored-by: Richard Schreiber <wiffbi@gmail.com>
This commit is contained in:
@@ -25,7 +25,7 @@ from io import BytesIO
|
|||||||
|
|
||||||
from django.core.files.base import ContentFile
|
from django.core.files.base import ContentFile
|
||||||
from django.core.files.storage import default_storage
|
from django.core.files.storage import default_storage
|
||||||
from PIL import Image, ImageOps
|
from PIL import Image, ImageOps, ImageSequence
|
||||||
from PIL.Image import Resampling
|
from PIL.Image import Resampling
|
||||||
|
|
||||||
from pretix.helpers.models import Thumbnail
|
from pretix.helpers.models import Thumbnail
|
||||||
@@ -171,12 +171,23 @@ def create_thumbnail(sourcename, size):
|
|||||||
except:
|
except:
|
||||||
raise ThumbnailError('Could not load image')
|
raise ThumbnailError('Could not load image')
|
||||||
|
|
||||||
image = resize_image(image, size)
|
frames = [resize_image(frame, size) for frame in ImageSequence.Iterator(image)]
|
||||||
|
image_out = frames[0]
|
||||||
|
save_kwargs = {}
|
||||||
|
|
||||||
if source.name.lower().endswith('.jpg') or source.name.lower().endswith('.jpeg'):
|
if source.name.lower().endswith('.jpg') or source.name.lower().endswith('.jpeg'):
|
||||||
# Yields better file sizes for photos
|
# Yields better file sizes for photos
|
||||||
target_ext = 'jpeg'
|
target_ext = 'jpeg'
|
||||||
quality = 95
|
quality = 95
|
||||||
|
elif source.name.lower().endswith('.gif') or source.name.lower().endswith('.png'):
|
||||||
|
target_ext = source.name.lower()[-3:]
|
||||||
|
quality = None
|
||||||
|
image_out.info = image.info
|
||||||
|
save_kwargs = {
|
||||||
|
'append_images': frames[1:],
|
||||||
|
'loop': image.info.get('loop', 0),
|
||||||
|
'save_all': True,
|
||||||
|
}
|
||||||
else:
|
else:
|
||||||
target_ext = 'png'
|
target_ext = 'png'
|
||||||
quality = None
|
quality = None
|
||||||
@@ -184,11 +195,11 @@ def create_thumbnail(sourcename, size):
|
|||||||
checksum = hashlib.md5(image.tobytes()).hexdigest()
|
checksum = hashlib.md5(image.tobytes()).hexdigest()
|
||||||
name = checksum + '.' + size.replace('^', 'c') + '.' + target_ext
|
name = checksum + '.' + size.replace('^', 'c') + '.' + target_ext
|
||||||
buffer = BytesIO()
|
buffer = BytesIO()
|
||||||
if image.mode == "P" and source.name.lower().endswith('.png'):
|
if image_out.mode == "P" and source.name.lower().endswith('.png'):
|
||||||
image = image.convert('RGBA')
|
image_out = image_out.convert('RGBA')
|
||||||
if image.mode not in ("1", "L", "RGB", "RGBA"):
|
if image_out.mode not in ("1", "L", "RGB", "RGBA"):
|
||||||
image = image.convert('RGB')
|
image_out = image_out.convert('RGB')
|
||||||
image.save(fp=buffer, format=target_ext.upper(), quality=quality)
|
image_out.save(fp=buffer, format=target_ext.upper(), quality=quality, **save_kwargs)
|
||||||
imgfile = ContentFile(buffer.getvalue())
|
imgfile = ContentFile(buffer.getvalue())
|
||||||
|
|
||||||
t = Thumbnail.objects.create(source=sourcename, size=size)
|
t = Thumbnail.objects.create(source=sourcename, size=size)
|
||||||
|
|||||||
Reference in New Issue
Block a user