Skip to content

Commit

Permalink
Avoid Pillow round-trip in desiger images (indico#6441)
Browse files Browse the repository at this point in the history
Co-authored-by: Adrian Moennich <[email protected]>
  • Loading branch information
tomako and ThiefMaster committed Jul 15, 2024
1 parent 6d2288c commit 8116460
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 13 deletions.
2 changes: 1 addition & 1 deletion indico/modules/designer/pdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def _draw_item(self, canvas, item, tpl_data, content, margin_x, margin_y):
item_height = (item['height'] / PIXELS_CM * cm) if item.get('height') is not None else None
item_preserve_aspect_ratio = item.get('preserve_aspect_ratio', True)

if isinstance(content, Image.Image):
if isinstance(content, BytesIO):
canvas.drawImage(ImageReader(content), margin_x + item_x, self.height - margin_y - item_height - item_y,
item_width, item_height, mask='auto', preserveAspectRatio=item_preserve_aspect_ratio)
else:
Expand Down
15 changes: 7 additions & 8 deletions indico/modules/designer/placeholders.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from io import BytesIO

from babel.numbers import format_currency
from PIL import Image

from indico.modules.designer.models.images import DesignerImageFile
from indico.modules.events.registration.util import generate_ticket_qr_code
Expand Down Expand Up @@ -105,8 +104,7 @@ class EventLogoPlaceholder(DesignerPlaceholder):
def render(cls, event):
if not event.has_logo:
return ''
buf = BytesIO(event.logo)
return Image.open(buf)
return BytesIO(event.logo)


class EventDatesPlaceholder(DesignerPlaceholder):
Expand Down Expand Up @@ -370,8 +368,8 @@ class RegistrationPicturePlaceholder(RegistrationPDPlaceholder):
@classmethod
def render(cls, registration):
if picture_data := registration.get_personal_data_picture():
buf = picture_data.open()
return Image.open(buf)
with picture_data.open() as fd:
return BytesIO(fd.read())
return None


Expand Down Expand Up @@ -406,8 +404,8 @@ class FixedImagePlaceholder(DesignerPlaceholder):

@classmethod
def render(cls, item):
buf = DesignerImageFile.get(item['image_id']).open()
return Image.open(buf)
with DesignerImageFile.get(item['image_id']).open() as fd:
return BytesIO(fd.read())


class RegistrationFormFieldPlaceholder(DesignerPlaceholder):
Expand Down Expand Up @@ -452,7 +450,8 @@ def _render(self, data):

def _render_image(self, data):
if data.storage_file_id is not None:
return Image.open(data.open())
with data.open() as fd:
return BytesIO(fd.read())

def _render_accommodation(self, friendly_data):
if friendly_data['is_no_accommodation']:
Expand Down
4 changes: 2 additions & 2 deletions indico/modules/designer/placeholders_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@

import itertools
from datetime import datetime
from io import BytesIO
from operator import attrgetter
from pathlib import Path

import pytest
from PIL import Image

from indico.modules.designer import placeholders
from indico.modules.events.models.persons import EventPerson, EventPersonLink
Expand Down Expand Up @@ -124,4 +124,4 @@ def test_render_image_placeholders(dummy_event, dummy_reg, dummy_designer_image_
for ph in image_placeholders:
kwargs = _get_render_kwargs(ph, dummy_event, dummy_person, dummy_reg, dummy_item)
res = ph.render(**kwargs)
assert isinstance(res, Image.Image) or res is None
assert isinstance(res, BytesIO) or res is None
8 changes: 6 additions & 2 deletions indico/modules/events/registration/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -736,9 +736,10 @@ def _base64_encode_uuid(uid):


def generate_ticket_qr_code(person):
"""Generate a Pillow `Image` with a QR Code encoding a check-in ticket.
"""Generate an image with a QR code encoding a check-in ticket.
:param registration: corresponding `Registration` object
:return: A `BytesIO` containing the image data
"""
qr = QRCode(
version=None,
Expand All @@ -750,7 +751,10 @@ def generate_ticket_qr_code(person):
qr_data = json.dumps(data, separators=(',', ':')) if not isinstance(data, str) else data
qr.add_data(qr_data)
qr.make(fit=True)
return qr.make_image()._img
buf = BytesIO()
qr.make_image().save(buf)
buf.seek(0)
return buf


def get_event_regforms(event, user, with_registrations=False, only_in_acl=False):
Expand Down

0 comments on commit 8116460

Please sign in to comment.