Уменьшение ширины / высоты изображения для соответствия заданному соотношению сторон. Как? - Миниатюры изображений Python

import Image

image  = Image.open('images/original.jpg')
width  = image.size[0]
height = image.size[1]

if width > height:
    difference = width - height
    offset     = difference / 2
    resize     = (offset, 0, width - offset, height)

else:
    difference = height - width
    offset     = difference / 2
    resize     = (0, offset, width, height - offset)

thumb = image.crop(resize).resize((200, 200), Image.ANTIALIAS)
thumb.save('thumb.jpg')

Это мой текущий сценарий создания миниатюр. Как это работает:

Если у вас есть изображение размером 400x300 и вам нужна миниатюра размером 100x100, это займет 50 пикселей с левой и правой стороны исходного изображения. Таким образом, изменив его размер до 300x300. Это дает исходному изображению такое же соотношение сторон, как и у нового эскиза. После этого он уменьшит его до необходимого размера эскиза.

Преимущества этого:

  • Миниатюра берется из центра изображения.
  • Соотношение сторон не испортится

Если вы уменьшите изображение размером 400x300 до 100x100, оно будет выглядеть сжатым. Если вы взяли миниатюру с координатами 0x0, вы получите верхний левый угол изображения. Обычно фокус изображения - это центр.

Что я хочу сделать, так это задать скрипту ширину / высоту любого соотношения сторон. Например, если я хочу изменить размер изображения 400x300 до 400x100, он должен уменьшить на 150 пикселей левую и правую стороны изображения ...

Я не могу придумать, как это сделать. Любые идеи?


person dave    schedule 20.01.2011    source источник
comment
То, что вы (и @Mark Longair в его ответе) называете изменением размера изображения, чаще называют его обрезкой. Изменение размера обычно означает масштабирование одного или обоих измерений.   -  person martineau    schedule 20.01.2011
comment
@martineau: Ну, он обрезает, а затем меняет размер - я просто оставил имя переменной как resize в вызове crop для согласованности с вопросом ...   -  person Mark Longair    schedule 20.01.2011
comment
Возможно, вы захотите просто масштабировать исходное изображение, чтобы оно соответствовало границам эскиза, вместо того, чтобы отрезать его часть. Это может оставить неиспользуемое пространство в прямоугольнике эскиза, но позволит избежать удаления какой-либо части оригинала. Это можно сделать, сравнив соотношения сторон, чтобы определить правильный масштабный коэффициент (тот, который будет масштабировать самый длинный размер, чтобы соответствовать соответствующему размеру (ширине или высоте) эскиза).   -  person martineau    schedule 20.01.2011


Ответы (1)


Вам просто нужно сравнить соотношение сторон - в зависимости от того, какое из них больше, это подскажет вам, нужно ли отрезать стороны или верх и низ. например как насчет:

import Image

image  = Image.open('images/original.jpg')
width  = image.size[0]
height = image.size[1]

aspect = width / float(height)

ideal_width = 200
ideal_height = 200

ideal_aspect = ideal_width / float(ideal_height)

if aspect > ideal_aspect:
    # Then crop the left and right edges:
    new_width = int(ideal_aspect * height)
    offset = (width - new_width) / 2
    resize = (offset, 0, width - offset, height)
else:
    # ... crop the top and bottom:
    new_height = int(width / ideal_aspect)
    offset = (height - new_height) / 2
    resize = (0, offset, width, height - offset)

thumb = image.crop(resize).resize((ideal_width, ideal_height), Image.ANTIALIAS)
thumb.save('thumb.jpg')
person Mark Longair    schedule 20.01.2011
comment
@greg: нет проблем - было бы неплохо, если бы вы тоже приняли ответ, в таком случае :) - person Mark Longair; 20.01.2011