Обрезать изображение в центре с помощью PIL

Как обрезать изображение в центре? Потому что я знаю, что ящик представляет собой 4-кортеж, определяющий координату слева, сверху, справа и ниже, но я не знаю, как получить эти координаты, чтобы они посеялись в центре.

Ответ 1

Предполагая, что вы знаете размер, который хотите обрезать (new_width X new_height):

import Image
im = Image.open(<your image>)
width, height = im.size   # Get dimensions

left = (width - new_width)/2
top = (height - new_height)/2
right = (width + new_width)/2
bottom = (height + new_height)/2

# Crop the center of the image
im = im.crop((left, top, right, bottom))

Это сломается, если вы попытаетесь обрезать маленькое изображение большего размера, но я собираюсь предположить, что вы не будете пытаться это сделать (или что вы можете поймать этот случай и не обрезать изображение).

Ответ 2

Одна потенциальная проблема с предлагаемым решением заключается в том, что существует нечетная разница между желаемым размером и старым размером. Вы не можете иметь половину пикселя на каждой стороне. Нужно выбрать сторону, чтобы добавить дополнительный пиксель.

Если есть нечетное различие для горизонтали, код ниже поместит дополнительный пиксель вправо, а если есть и нечетное различие по вертикали, дополнительный пиксель переместится вниз.

import numpy as np

def center_crop(img, new_width=None, new_height=None):        

    width = img.shape[1]
    height = img.shape[0]

    if new_width is None:
        new_width = min(width, height)

    if new_height is None:
        new_height = min(width, height)

    left = int(np.ceil((width - new_width) / 2))
    right = width - int(np.floor((width - new_width) / 2))

    top = int(np.ceil((height - new_height) / 2))
    bottom = height - int(np.floor((height - new_height) / 2))

    if len(img.shape) == 2:
        center_cropped_img = img[top:bottom, left:right]
    else:
        center_cropped_img = img[top:bottom, left:right, ...]

    return center_cropped_img

Ответ 3

Это функция, которую я искал:

from PIL import Image
im = Image.open("test.jpg")

crop_rectangle = (50, 50, 200, 200)
cropped_im = im.crop(crop_rectangle)

cropped_im.show()

Взято из другого ответа