diff --git a/Tests/test_image_thumbnail.py b/Tests/test_image_thumbnail.py index de15f5e2e98..f4ed8e746ff 100644 --- a/Tests/test_image_thumbnail.py +++ b/Tests/test_image_thumbnail.py @@ -38,9 +38,9 @@ def test_aspect(): im.thumbnail((100, 50)) assert im.size == (100, 50) - im = Image.new("L", (128, 128)) + im = Image.new("L", (64, 64)) 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.thumbnail((33, 33)) @@ -50,11 +50,23 @@ def test_aspect(): im.thumbnail((33, 33)) 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(): im = Image.new("L", (128, 128)) im.thumbnail((99.9, 99.9)) - assert im.size == (100, 100) + assert im.size == (99, 99) def test_no_resize(): diff --git a/src/PIL/Image.py b/src/PIL/Image.py index dec94f2d053..b1e8ad3ea06 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -2236,20 +2236,22 @@ def thumbnail(self, size, resample=BICUBIC, reducing_gap=2.0): :returns: None """ - # preserve aspect ratio - x, y = self.size - 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: + x, y = map(math.floor, size) + if x >= self.width and y >= self.height: 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: res = self.draft(None, (size[0] * reducing_gap, size[1] * reducing_gap)) if res is not None: