From 26f6d8f076e6645b47f85034bbaa4319565405f7 Mon Sep 17 00:00:00 2001 From: Jeff <138259519+jdotc1@users.noreply.github.com> Date: Wed, 21 Oct 2026 14:43:29 -0400 Subject: [PATCH 1/2] Handle zero-width images in ImageOps.cover --- Tests/test_imageops.py | 22 ++++++++++++++++++++++ docs/releasenotes/13.1.0.rst | 7 +++++++ src/PIL/ImageOps.py | 2 ++ 3 files changed, 31 insertions(+) diff --git a/Tests/test_imageops.py b/Tests/test_imageops.py index c40213476f3..8342fc82099 100644 --- a/Tests/test_imageops.py +++ b/Tests/test_imageops.py @@ -202,6 +202,28 @@ def test_cover_zero() -> None: assert new_im.size == (0, 0) +@pytest.mark.parametrize("mode", ("1", "L", "RGB", "RGBA")) +@pytest.mark.parametrize( + "source_size, target_size, expected_size", + [ + ((0, 10), (5, 5), (0, 5)), + ((0, 10), (3, 7), (0, 7)), + ((0, 10), (3, 0), (0, 0)), + ((0, 0), (3, 7), (3, 0)), + ], +) +def test_cover_zero_width( + mode: str, + source_size: tuple[int, int], + target_size: tuple[int, int], + expected_size: tuple[int, int], +) -> None: + im = Image.new(mode, source_size) + result = ImageOps.cover(im, target_size) + assert result.size == expected_size + assert result.mode == mode + + def test_pad() -> None: # Same ratio im = hopper() diff --git a/docs/releasenotes/13.1.0.rst b/docs/releasenotes/13.1.0.rst index 140bcbe3115..dd8830c6a4c 100644 --- a/docs/releasenotes/13.1.0.rst +++ b/docs/releasenotes/13.1.0.rst @@ -49,6 +49,13 @@ TODO Other changes ============= +Covering zero-width images +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +:py:func:`~PIL.ImageOps.cover` now handles a zero-width image with nonzero height +by returning an image with zero width and the requested height, instead of +raising :py:exc:`ZeroDivisionError`. + Blurring I;16 images ^^^^^^^^^^^^^^^^^^^^ diff --git a/src/PIL/ImageOps.py b/src/PIL/ImageOps.py index 364bcc90911..5d44cb72ae3 100644 --- a/src/PIL/ImageOps.py +++ b/src/PIL/ImageOps.py @@ -351,6 +351,8 @@ def cover( if image.height == 0: return Image.new(image.mode, (size[0], 0)) + if image.width == 0: + return Image.new(image.mode, (0, size[1])) im_ratio = image.width / image.height if size[1] == 0: return Image.new(image.mode, (0, 0)) From 16c2cc742bca5ec7033394d30a5c48b7ba000366 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Thu, 22 Oct 2026 09:58:24 +1100 Subject: [PATCH 2/2] Simplify tests --- Tests/test_imageops.py | 26 ++++---------------------- docs/releasenotes/13.1.0.rst | 7 ------- src/PIL/ImageOps.py | 4 ++-- 3 files changed, 6 insertions(+), 31 deletions(-) diff --git a/Tests/test_imageops.py b/Tests/test_imageops.py index 8342fc82099..c52d3420e8f 100644 --- a/Tests/test_imageops.py +++ b/Tests/test_imageops.py @@ -193,6 +193,10 @@ def test_cover(image_name: str, expected_size: tuple[int, int]) -> None: def test_cover_zero() -> None: + im = Image.new("1", (0, 10)) + new_im = ImageOps.cover(im, (5, 5)) + assert new_im.size == (0, 5) + im = Image.new("1", (10, 0)) new_im = ImageOps.cover(im, (5, 5)) assert new_im.size == (5, 0) @@ -202,28 +206,6 @@ def test_cover_zero() -> None: assert new_im.size == (0, 0) -@pytest.mark.parametrize("mode", ("1", "L", "RGB", "RGBA")) -@pytest.mark.parametrize( - "source_size, target_size, expected_size", - [ - ((0, 10), (5, 5), (0, 5)), - ((0, 10), (3, 7), (0, 7)), - ((0, 10), (3, 0), (0, 0)), - ((0, 0), (3, 7), (3, 0)), - ], -) -def test_cover_zero_width( - mode: str, - source_size: tuple[int, int], - target_size: tuple[int, int], - expected_size: tuple[int, int], -) -> None: - im = Image.new(mode, source_size) - result = ImageOps.cover(im, target_size) - assert result.size == expected_size - assert result.mode == mode - - def test_pad() -> None: # Same ratio im = hopper() diff --git a/docs/releasenotes/13.1.0.rst b/docs/releasenotes/13.1.0.rst index dd8830c6a4c..140bcbe3115 100644 --- a/docs/releasenotes/13.1.0.rst +++ b/docs/releasenotes/13.1.0.rst @@ -49,13 +49,6 @@ TODO Other changes ============= -Covering zero-width images -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -:py:func:`~PIL.ImageOps.cover` now handles a zero-width image with nonzero height -by returning an image with zero width and the requested height, instead of -raising :py:exc:`ZeroDivisionError`. - Blurring I;16 images ^^^^^^^^^^^^^^^^^^^^ diff --git a/src/PIL/ImageOps.py b/src/PIL/ImageOps.py index 5d44cb72ae3..b40af6330bb 100644 --- a/src/PIL/ImageOps.py +++ b/src/PIL/ImageOps.py @@ -349,10 +349,10 @@ def cover( :return: An image. """ - if image.height == 0: - return Image.new(image.mode, (size[0], 0)) if image.width == 0: return Image.new(image.mode, (0, size[1])) + if image.height == 0: + return Image.new(image.mode, (size[0], 0)) im_ratio = image.width / image.height if size[1] == 0: return Image.new(image.mode, (0, 0))