Merge pull request #3364 from radarhere/contain

Added ImageOps pad method
This commit is contained in:
Hugo 2018-09-26 13:54:26 +03:00 committed by GitHub
commit 78203606b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 68 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -24,6 +24,9 @@ class TestImageOps(PillowTestCase):
ImageOps.colorize(hopper("L"), (0, 0, 0), (255, 255, 255))
ImageOps.colorize(hopper("L"), "black", "white")
ImageOps.pad(hopper("L"), (128, 128))
ImageOps.pad(hopper("RGB"), (128, 128))
ImageOps.crop(hopper("L"), 1)
ImageOps.crop(hopper("RGB"), 1)
@ -70,6 +73,27 @@ class TestImageOps(PillowTestCase):
newimg = ImageOps.fit(hopper("RGB").resize((100, 1)), (35, 35))
self.assertEqual(newimg.size, (35, 35))
def test_pad(self):
# Same ratio
im = hopper()
new_size = (im.width * 2, im.height * 2)
new_im = ImageOps.pad(im, new_size)
self.assertEqual(new_im.size, new_size)
for label, color, new_size in [
("h", None, (im.width * 4, im.height * 2)),
("v", "#f00", (im.width * 2, im.height * 4))
]:
for i, centering in enumerate([(0,0), (0.5, 0.5), (1, 1)]):
new_im = ImageOps.pad(im, new_size,
color=color, centering=centering)
self.assertEqual(new_im.size, new_size)
target = Image.open(
"Tests/images/imageops_pad_"+label+"_"+str(i)+".jpg")
self.assert_image_similar(new_im, target, 6)
def test_pil163(self):
# Division by zero in equalize if < 255 pixels in image (@PIL163)

View File

@ -221,6 +221,50 @@ def colorize(image, black, white, mid=None, blackpoint=0,
return _lut(image, red + green + blue)
def pad(image, size, method=Image.NEAREST, color=None, centering=(0.5, 0.5)):
"""
Returns a sized and padded version of the image, expanded to fill the
requested aspect ratio and size.
:param image: The image to size and crop.
:param size: The requested output size in pixels, given as a
(width, height) tuple.
:param method: What resampling method to use. Default is
:py:attr:`PIL.Image.NEAREST`.
:param color: The background color of the padded image.
:param centering: Control the position of the original image within the
padded version.
(0.5, 0.5) will keep the image centered
(0, 0) will keep the image aligned to the top left
(1, 1) will keep the image aligned to the bottom
right
:return: An image.
"""
im_ratio = image.width / image.height
dest_ratio = float(size[0]) / size[1]
if im_ratio == dest_ratio:
out = image.resize(size, resample=method)
else:
out = Image.new(image.mode, size, color)
if im_ratio > dest_ratio:
new_height = int(image.height / image.width * size[0])
if new_height != size[1]:
image = image.resize((size[0], new_height), resample=method)
y = int((size[1] - new_height) * max(0, min(centering[1], 1)))
out.paste(image, (0, y))
else:
new_width = int(image.width / image.height * size[1])
if new_width != size[0]:
image = image.resize((new_width, size[1]), resample=method)
x = int((size[0] - new_width) * max(0, min(centering[0], 1)))
out.paste(image, (x, 0))
return out
def crop(image, border=0):
"""
Remove border from image. The same amount of pixels are removed