Skip to content

Commit 79a3fe1

Browse files
committed
Added ImageOps cover method
1 parent 7a633e3 commit 79a3fe1

File tree

3 files changed

+48
-1
lines changed

3 files changed

+48
-1
lines changed

Tests/test_imageops.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ def test_sanity():
3939
ImageOps.contain(hopper("L"), (128, 128))
4040
ImageOps.contain(hopper("RGB"), (128, 128))
4141

42+
ImageOps.cover(hopper("L"), (128, 128))
43+
ImageOps.cover(hopper("RGB"), (128, 128))
44+
4245
ImageOps.crop(hopper("L"), 1)
4346
ImageOps.crop(hopper("RGB"), 1)
4447

@@ -119,6 +122,20 @@ def test_contain_round():
119122
assert new_im.height == 5
120123

121124

125+
@pytest.mark.parametrize(
126+
"image_name, expected_size",
127+
(
128+
("colr_bungee.png", (1024, 256)), # landscape
129+
("imagedraw_stroke_multiline.png", (256, 640)), # portrait
130+
("hopper.png", (256, 256)), # square
131+
),
132+
)
133+
def test_cover(image_name, expected_size):
134+
with Image.open("Tests/images/" + image_name) as im:
135+
new_im = ImageOps.cover(im, (256, 256))
136+
assert new_im.size == expected_size
137+
138+
122139
def test_pad():
123140
# Same ratio
124141
im = hopper()

docs/reference/ImageOps.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ only work on L and RGB images.
1313
.. autofunction:: autocontrast
1414
.. autofunction:: colorize
1515
.. autofunction:: contain
16+
.. autofunction:: cover
1617
.. autofunction:: pad
1718
.. autofunction:: crop
1819
.. autofunction:: scale

src/PIL/ImageOps.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ def contain(image, size, method=Image.Resampling.BICUBIC):
242242
Returns a resized version of the image, set to the maximum width and height
243243
within the requested size, while maintaining the original aspect ratio.
244244
245-
:param image: The image to resize and crop.
245+
:param image: The image to resize.
246246
:param size: The requested output size in pixels, given as a
247247
(width, height) tuple.
248248
:param method: Resampling method to use. Default is
@@ -266,6 +266,35 @@ def contain(image, size, method=Image.Resampling.BICUBIC):
266266
return image.resize(size, resample=method)
267267

268268

269+
def cover(image, size, method=Image.Resampling.BICUBIC):
270+
"""
271+
Returns a resized version of the image, set to at least the width and
272+
height of the requested size, while maintaining the original aspect ratio.
273+
274+
:param image: The image to resize.
275+
:param size: The requested output size in pixels, given as a
276+
(width, height) tuple.
277+
:param method: Resampling method to use. Default is
278+
:py:attr:`~PIL.Image.Resampling.BICUBIC`.
279+
See :ref:`concept-filters`.
280+
:return: An image.
281+
"""
282+
283+
im_ratio = image.width / image.height
284+
dest_ratio = size[0] / size[1]
285+
286+
if im_ratio != dest_ratio:
287+
if im_ratio < dest_ratio:
288+
new_height = round(image.height / image.width * size[0])
289+
if new_height != size[1]:
290+
size = (size[0], new_height)
291+
else:
292+
new_width = round(image.width / image.height * size[1])
293+
if new_width != size[0]:
294+
size = (new_width, size[1])
295+
return image.resize(size, resample=method)
296+
297+
269298
def pad(image, size, method=Image.Resampling.BICUBIC, color=None, centering=(0.5, 0.5)):
270299
"""
271300
Returns a resized and padded version of the image, expanded to fill the

0 commit comments

Comments
 (0)