Do not call load() before draft()

This commit is contained in:
Andrew Murray 2022-08-26 20:33:51 +10:00
parent ba98fe7829
commit 38b53a9fd7
2 changed files with 49 additions and 15 deletions

View File

@ -97,6 +97,28 @@ def test_load_first():
im.thumbnail((64, 64)) im.thumbnail((64, 64))
assert im.size == (64, 10) assert im.size == (64, 10)
# Test thumbnail(), without draft(),
# on an image that is large enough once load() has changed the size
with Image.open("Tests/images/g4_orientation_5.tif") as im:
im.thumbnail((590, 88), reducing_gap=None)
assert im.size == (590, 88)
def test_load_first_unless_jpeg():
# Test that thumbnail() still uses draft() for JPEG
with Image.open("Tests/images/hopper.jpg") as im:
draft = im.draft
def im_draft(mode, size):
result = draft(mode, size)
assert result is not None
return result
im.draft = im_draft
im.thumbnail((64, 64))
# valgrind test is failing with memory allocated in libjpeg # valgrind test is failing with memory allocated in libjpeg
@pytest.mark.valgrind_known_error(reason="Known Failing") @pytest.mark.valgrind_known_error(reason="Known Failing")

View File

@ -2473,29 +2473,41 @@ class Image:
:returns: None :returns: None
""" """
self.load() provided_size = tuple(map(math.floor, size))
x, y = map(math.floor, size)
if x >= self.width and y >= self.height:
return
def round_aspect(number, key): def preserve_aspect_ratio():
return max(min(math.floor(number), math.ceil(number), key=key), 1) def round_aspect(number, key):
return max(min(math.floor(number), math.ceil(number), key=key), 1)
# preserve aspect ratio x, y = provided_size
aspect = self.width / self.height if x >= self.width and y >= self.height:
if x / y >= aspect: return
x = round_aspect(y * aspect, key=lambda n: abs(aspect - n / y))
else: aspect = self.width / self.height
y = round_aspect( if x / y >= aspect:
x / aspect, key=lambda n: 0 if n == 0 else abs(aspect - x / n) x = round_aspect(y * aspect, key=lambda n: abs(aspect - n / y))
) else:
size = (x, y) y = round_aspect(
x / aspect, key=lambda n: 0 if n == 0 else abs(aspect - x / n)
)
return x, y
box = None box = None
if reducing_gap is not None: if reducing_gap is not None:
size = preserve_aspect_ratio()
if size is None:
return
res = self.draft(None, (size[0] * reducing_gap, size[1] * reducing_gap)) res = self.draft(None, (size[0] * reducing_gap, size[1] * reducing_gap))
if res is not None: if res is not None:
box = res[1] box = res[1]
if box is None:
self.load()
# load() may have changed the size of the image
size = preserve_aspect_ratio()
if size is None:
return
if self.size != size: if self.size != size:
im = self.resize(size, resample, box=box, reducing_gap=reducing_gap) im = self.resize(size, resample, box=box, reducing_gap=reducing_gap)