mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-03-23 19:44:13 +03:00
Optimise ImageOps.fit by combining resize in crop
This commit is contained in:
parent
0ac14725ef
commit
73eec9000d
|
@ -380,9 +380,10 @@ def fit(image, size, method=Image.NEAREST, bleed=0.0, centering=(0.5, 0.5)):
|
||||||
(width, height) tuple.
|
(width, height) tuple.
|
||||||
:param method: What resampling method to use. Default is
|
:param method: What resampling method to use. Default is
|
||||||
:py:attr:`PIL.Image.NEAREST`.
|
:py:attr:`PIL.Image.NEAREST`.
|
||||||
:param bleed: Remove a border around the outside of the image (from all
|
:param bleed: Remove a border around the outside of the image from all
|
||||||
four edges. The value is a decimal percentage (use 0.01 for
|
four edges. The value is a decimal percentage (use 0.01 for
|
||||||
one percent). The default value is 0 (no border).
|
one percent). The default value is 0 (no border).
|
||||||
|
Cannot be greater than or equal to 0.5.
|
||||||
:param centering: Control the cropping position. Use (0.5, 0.5) for
|
:param centering: Control the cropping position. Use (0.5, 0.5) for
|
||||||
center cropping (e.g. if cropping the width, take 50% off
|
center cropping (e.g. if cropping the width, take 50% off
|
||||||
of the left side, and therefore 50% off the right side).
|
of the left side, and therefore 50% off the right side).
|
||||||
|
@ -400,66 +401,50 @@ def fit(image, size, method=Image.NEAREST, bleed=0.0, centering=(0.5, 0.5)):
|
||||||
# kevin@cazabon.com
|
# kevin@cazabon.com
|
||||||
# http://www.cazabon.com
|
# http://www.cazabon.com
|
||||||
|
|
||||||
# ensure inputs are valid
|
# ensure centering is mutable
|
||||||
if not isinstance(centering, list):
|
centering = list(centering)
|
||||||
centering = [centering[0], centering[1]]
|
|
||||||
|
|
||||||
if centering[0] > 1.0 or centering[0] < 0.0:
|
if not 0.0 <= centering[0] <= 1.0:
|
||||||
centering[0] = 0.50
|
centering[0] = 0.5
|
||||||
if centering[1] > 1.0 or centering[1] < 0.0:
|
if not 0.0 <= centering[1] <= 1.0:
|
||||||
centering[1] = 0.50
|
centering[1] = 0.5
|
||||||
|
|
||||||
if bleed > 0.49999 or bleed < 0.0:
|
if not 0.0 <= bleed < 0.5:
|
||||||
bleed = 0.0
|
bleed = 0.0
|
||||||
|
|
||||||
# calculate the area to use for resizing and cropping, subtracting
|
# calculate the area to use for resizing and cropping, subtracting
|
||||||
# the 'bleed' around the edges
|
# the 'bleed' around the edges
|
||||||
|
|
||||||
# number of pixels to trim off on Top and Bottom, Left and Right
|
# number of pixels to trim off on Top and Bottom, Left and Right
|
||||||
bleedPixels = (
|
bleed_pixels = (bleed * image.size[0], bleed * image.size[1])
|
||||||
int((float(bleed) * float(image.size[0])) + 0.5),
|
|
||||||
int((float(bleed) * float(image.size[1])) + 0.5)
|
|
||||||
)
|
|
||||||
|
|
||||||
liveArea = (0, 0, image.size[0], image.size[1])
|
live_size = (image.size[0] - bleed_pixels[0] * 2,
|
||||||
if bleed > 0.0:
|
image.size[1] - bleed_pixels[1] * 2)
|
||||||
liveArea = (
|
|
||||||
bleedPixels[0], bleedPixels[1], image.size[0] - bleedPixels[0] - 1,
|
|
||||||
image.size[1] - bleedPixels[1] - 1
|
|
||||||
)
|
|
||||||
|
|
||||||
liveSize = (liveArea[2] - liveArea[0], liveArea[3] - liveArea[1])
|
# calculate the aspect ratio of the live_size
|
||||||
|
live_size_ratio = float(live_size[0]) / live_size[1]
|
||||||
# calculate the aspect ratio of the liveArea
|
|
||||||
liveAreaAspectRatio = float(liveSize[0])/float(liveSize[1])
|
|
||||||
|
|
||||||
# calculate the aspect ratio of the output image
|
# calculate the aspect ratio of the output image
|
||||||
aspectRatio = float(size[0]) / float(size[1])
|
output_ratio = float(size[0]) / size[1]
|
||||||
|
|
||||||
# figure out if the sides or top/bottom will be cropped off
|
# figure out if the sides or top/bottom will be cropped off
|
||||||
if liveAreaAspectRatio >= aspectRatio:
|
if live_size_ratio >= output_ratio:
|
||||||
# liveArea is wider than what's needed, crop the sides
|
# live_size is wider than what's needed, crop the sides
|
||||||
cropWidth = int((aspectRatio * float(liveSize[1])) + 0.5)
|
crop_width = output_ratio * live_size[1]
|
||||||
cropHeight = liveSize[1]
|
crop_height = live_size[1]
|
||||||
else:
|
else:
|
||||||
# liveArea is taller than what's needed, crop the top and bottom
|
# live_size is taller than what's needed, crop the top and bottom
|
||||||
cropWidth = liveSize[0]
|
crop_width = live_size[0]
|
||||||
cropHeight = int((float(liveSize[0])/aspectRatio) + 0.5)
|
crop_height = live_size[0] / output_ratio
|
||||||
|
|
||||||
# make the crop
|
# make the crop
|
||||||
leftSide = int(liveArea[0] + (float(liveSize[0]-cropWidth) * centering[0]))
|
crop_left = bleed_pixels[0] + (live_size[0]-crop_width) * centering[0]
|
||||||
if leftSide < 0:
|
crop_top = bleed_pixels[1] + (live_size[1]-crop_height) * centering[1]
|
||||||
leftSide = 0
|
|
||||||
topSide = int(liveArea[1] + (float(liveSize[1]-cropHeight) * centering[1]))
|
|
||||||
if topSide < 0:
|
|
||||||
topSide = 0
|
|
||||||
|
|
||||||
out = image.crop(
|
crop = (crop_left, crop_top, crop_left + crop_width, crop_top + crop_height)
|
||||||
(leftSide, topSide, leftSide + cropWidth, topSide + cropHeight)
|
|
||||||
)
|
|
||||||
|
|
||||||
# resize the image and return it
|
# resize the image and return it
|
||||||
return out.resize(size, method)
|
return image.resize(size, method, box=crop)
|
||||||
|
|
||||||
|
|
||||||
def flip(image):
|
def flip(image):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user