Merge pull request #4404 from orlnub123/bugfix/thumbnail

Fix size calculation of Image.thumbnail()
This commit is contained in:
Hugo van Kemenade 2020-03-06 00:33:03 +02:00 committed by GitHub
commit 3f9b615349
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 15 deletions

View File

@ -38,9 +38,9 @@ def test_aspect():
im.thumbnail((100, 50)) im.thumbnail((100, 50))
assert im.size == (100, 50) assert im.size == (100, 50)
im = Image.new("L", (128, 128)) im = Image.new("L", (64, 64))
im.thumbnail((100, 100)) im.thumbnail((100, 100))
assert im.size == (100, 100) assert im.size == (64, 64)
im = Image.new("L", (256, 162)) # ratio is 1.5802469136 im = Image.new("L", (256, 162)) # ratio is 1.5802469136
im.thumbnail((33, 33)) im.thumbnail((33, 33))
@ -50,11 +50,23 @@ def test_aspect():
im.thumbnail((33, 33)) im.thumbnail((33, 33))
assert im.size == (21, 33) # ratio is 0.6363636364 assert im.size == (21, 33) # ratio is 0.6363636364
im = Image.new("L", (145, 100)) # ratio is 1.45
im.thumbnail((50, 50))
assert im.size == (50, 34) # ratio is 1.47058823529
im = Image.new("L", (100, 145)) # ratio is 0.689655172414
im.thumbnail((50, 50))
assert im.size == (34, 50) # ratio is 0.68
im = Image.new("L", (100, 30)) # ratio is 3.333333333333
im.thumbnail((75, 75))
assert im.size == (75, 23) # ratio is 3.260869565217
def test_float(): def test_float():
im = Image.new("L", (128, 128)) im = Image.new("L", (128, 128))
im.thumbnail((99.9, 99.9)) im.thumbnail((99.9, 99.9))
assert im.size == (100, 100) assert im.size == (99, 99)
def test_no_resize(): def test_no_resize():

View File

@ -2236,20 +2236,22 @@ class Image:
:returns: None :returns: None
""" """
# preserve aspect ratio x, y = map(math.floor, size)
x, y = self.size if x >= self.width and y >= self.height:
if x > size[0]:
y = max(round(y * size[0] / x), 1)
x = round(size[0])
if y > size[1]:
x = max(round(x * size[1] / y), 1)
y = round(size[1])
size = x, y
box = None
if size == self.size:
return return
def round_aspect(number, key):
return max(min(math.floor(number), math.ceil(number), key=key), 1)
# preserve aspect ratio
aspect = self.width / self.height
if x / y >= aspect:
x = round_aspect(y * aspect, key=lambda n: abs(aspect - n / y))
else:
y = round_aspect(x / aspect, key=lambda n: abs(aspect - x / n))
size = (x, y)
box = None
if reducing_gap is not None: if reducing_gap is not None:
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: