Skip to content

Commit 93df1a5

Browse files
committed
Don’t resize the same image twice when the --dpi option is set
It also avoids crashes with PNG images, as the incomplete PNG part used in the PDF was read by Pillow the second time instead of the whole PNG file.
1 parent b64c369 commit 93df1a5

File tree

2 files changed

+17
-16
lines changed

2 files changed

+17
-16
lines changed

weasyprint/images.py

+3-14
Original file line numberDiff line numberDiff line change
@@ -94,28 +94,17 @@ def draw(self, stream, concrete_width, concrete_height, image_rendering):
9494
return
9595

9696
width, height = self.width, self.height
97+
interpolate = 'true' if image_rendering == 'auto' else 'false'
98+
ratio = 1
9799
if self._dpi:
98100
pt_to_in = 4 / 3 / 96
99101
width_inches = abs(concrete_width * stream.ctm[0][0] * pt_to_in)
100102
height_inches = abs(concrete_height * stream.ctm[1][1] * pt_to_in)
101103
dpi = max(self.width / width_inches, self.height / height_inches)
102104
if dpi > self._dpi:
103105
ratio = self._dpi / dpi
104-
image = Image.open(io.BytesIO(self.image_data.data))
105-
width = int(round(self.width * ratio))
106-
height = int(round(self.height * ratio))
107-
image.thumbnail((max(1, width), max(1, height)))
108-
image_file = io.BytesIO()
109-
image.save(
110-
image_file, format=image.format, optimize=self.optimize)
111-
width, height = image.width, image.height
112-
self.image_data = self.cache_image_data(image_file.getvalue())
113-
else:
114-
dpi = None
115-
116-
interpolate = 'true' if image_rendering == 'auto' else 'false'
106+
image_name = stream.add_image(self, width, height, interpolate, ratio)
117107

118-
image_name = stream.add_image(self, width, height, interpolate)
119108
stream.transform(
120109
concrete_width, 0, 0, -concrete_height, 0, concrete_height)
121110
stream.draw_x_object(image_name)

weasyprint/pdf/stream.py

+14-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from fontTools import subset
99
from fontTools.ttLib import TTFont, TTLibError, ttFont
1010
from fontTools.varLib.mutator import instantiateVariableFont
11+
from PIL import Image
1112

1213
from ..logger import LOGGER
1314
from ..matrix import Matrix
@@ -361,13 +362,24 @@ def add_group(self, x, y, width, height):
361362
self._x_objects[group.id] = group
362363
return group
363364

364-
def add_image(self, image, width, height, interpolate):
365-
image_name = f'i{image.id}{width}{height}{interpolate}'
365+
def add_image(self, image, width, height, interpolate, ratio):
366+
image_name = f'i{image.id}{width}{height}{interpolate}{ratio}'
366367
self._x_objects[image_name] = None # Set by write_pdf
367368
if image_name in self._images:
368369
# Reuse image already stored in document
369370
return image_name
370371

372+
if ratio != 1:
373+
thumbnail = Image.open(io.BytesIO(image.image_data.data))
374+
width = int(round(image.width * ratio))
375+
height = int(round(image.height * ratio))
376+
thumbnail.thumbnail((max(1, width), max(1, height)))
377+
image_file = io.BytesIO()
378+
thumbnail.save(
379+
image_file, format=thumbnail.format, optimize=image.optimize)
380+
width, height = thumbnail.width, thumbnail.height
381+
image.image_data = image.cache_image_data(image_file.getvalue())
382+
371383
xobject = image.get_xobject(width, height, interpolate)
372384
self._images[image_name] = xobject
373385
return image_name

0 commit comments

Comments
 (0)