Вы должны рассчитать центр вашего урожая и использовать его там.Например:
crop_width = right - left
crop_height = bottom - top
crop_center_x = int(left + crop_width/2)
crop_center_y = (top + crop_height/2)
Таким образом, вы получите точку (x, y), которая соответствует центру вашего урожая по сравнению с вашим исходным изображением.В этом случае вы будете знать, что максимальная ширина для вашей обрезки будет минимум между значением центра и внешними границами исходного изображения минус сам центр:
im = Image.open("brad.jpg")
l = 200
t = 200
r = 300
b = 300
cropped = im.crop((l, t, r, b))
Что дает вам:
Если вы хотите «увеличить» его до максимума, начиная с того же центра, то у вас будет:
max_width = min(crop_center_x, im.size[0]-crop_center_x)
max_height = min(crop_center_y, im.size[1]-crop_center_y)
new_l = crop_center_x - max_width
new_t = crop_center_x - max_height
new_r = crop_center_x + max_width
new_b = crop_center_x + max_height
new_crop = im.crop((new_l, new_t, new_r, new_b))
, что в результате дает тот же центр:
Редактировать
Если выЕсли вы хотите сохранить соотношение сторон, вы должны восстановить его (соотношение) и применять обрезку только в том случае, если полученный размер все еще будет соответствовать исходному изображению.Например, если вы хотите увеличить его на 20%:
ratio = crop_height/crop_width
scale = 20/100
new_width = int(crop_width + (crop_width*scale))
# Here we are using the previously calculated value for max_width to
# determine if the new one would be too large.
# Note that the width that we calculated here (new_width) refers to both
# sides of the crop, while the max_width calculated previously refers to
# one side only; same for height. Sorry for the confusion.
if max_width < new_width/2:
new_width = int(2*max_width)
new_height = int(new_width*ratio)
# Do the same for the height, update width if necessary
if max_height < new_height/2:
new_height = int(2*max_height)
new_width = int(new_height/ratio)
adjusted_scale = (new_width - crop_width)/crop_width
if adjusted_scale != scale:
print("Scale adjusted to: {:.2f}".format(adjusted_scale))
new_l = int(crop_center_x - new_width/2)
new_r = int(crop_center_x + new_width/2)
new_t = int(crop_center_y - new_height/2)
new_b = int(crop_center_y + new_height/2)
Когда у вас есть значения ширины и высоты, процесс получения обрезки такой же, как и выше.