Какой самый простой способ изменить размер изображения в заданной ограниченной области? - PullRequest
2 голосов
/ 06 октября 2010

Я бы хотел создать функцию, например:

def generateThumbnail(self, width, height):
     """
     Generates thumbnails for an image
     """
     im = Image.open(self._file)
     im.thumbnail((width, height), Image.ANTIALIAS)
     im.save(self._path + str(width) + 'x' + 
             str(height) + '-' + self._filename, "JPEG")

Где файл может быть передан и изменен в размере.

Текущая функция отлично работает, за исключением того, что она не обрезается при необходимости.

В случае, если задано прямоугольное изображение и требуется квадратное изменение размера (ширина = высота), необходимо выполнить некоторое центрированное взвешивание.

1 Ответ

5 голосов
/ 06 октября 2010

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

def cropbbox(imagewidth,imageheight, thumbwidth,thumbheight):
    """ cropbbox(imagewidth,imageheight, thumbwidth,thumbheight)

        Compute a centered image crop area for making thumbnail images.
          imagewidth,imageheight are source image dimensions
          thumbwidth,thumbheight are thumbnail image dimensions

        Returns bounding box pixel coordinates of the cropping area
        in this order (left,upper, right,lower).
    """
    # determine scale factor
    fx = float(imagewidth)/thumbwidth
    fy = float(imageheight)/thumbheight
    f = fx if fx < fy else fy

    # calculate size of crop area
    cropheight,cropwidth = int(thumbheight*f),int(thumbwidth*f)

    # for centering use half the size difference of the image and the crop area
    dx = (imagewidth-cropwidth)/2
    dy = (imageheight-cropheight)/2

    # return bounding box of centered crop area on source image
    return dx,dy, cropwidth+dx,cropheight+dy


if __name__=='__main__':

    print("===")
    bbox = cropbbox(1024,768, 128,128)
    print("cropbbox(1024,768, 128,128): {}".format(bbox))

    print("===")
    bbox = cropbbox(768,1024, 128,128)
    print("cropbbox(768,1024, 128,128): {}".format(bbox))

    print("===")
    bbox = cropbbox(1024,1024, 96,128)
    print("cropbbox(1024,1024, 96,128): {}".format(bbox))

    print("===")
    bbox = cropbbox(1024,1024, 128,96)
    print("cropbbox(1024,1024, 128,96): {}".format(bbox))

После определения области обрезки позвоните im.crop(bbox) и затем вызовите im.thumbnail(...) на возвращенном изображении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...