Как изменить размер изображения с помощью PIL и сохранить его соотношение сторон? - PullRequest
351 голосов
/ 08 ноября 2008

Есть ли очевидный способ сделать это, что мне не хватает? Я просто пытаюсь делать эскизы.

Ответы [ 14 ]

413 голосов
/ 08 ноября 2008

Определите максимальный размер. Затем вычислите коэффициент изменения размера, взяв min(maxwidth/width, maxheight/height).

Правильный размер oldsize*ratio.

Конечно, есть и библиотечный метод для этого: метод Image.thumbnail.
Ниже приведен (отредактированный) пример из документации PIL .

import os, sys
import Image

size = 128, 128

for infile in sys.argv[1:]:
    outfile = os.path.splitext(infile)[0] + ".thumbnail"
    if infile != outfile:
        try:
            im = Image.open(infile)
            im.thumbnail(size, Image.ANTIALIAS)
            im.save(outfile, "JPEG")
        except IOError:
            print "cannot create thumbnail for '%s'" % infile
200 голосов
/ 16 января 2009

Этот скрипт изменит размер изображения (somepic.jpg) с помощью PIL (Python Imaging Library) до ширины 300 пикселей и высоты, пропорциональной новой ширине. Он делает это, определяя, какой процент 300 пикселей имеет исходную ширину (img.size [0]), а затем умножая исходную высоту (img.size [1]) на этот процент. Измените «basewidth» на любое другое число, чтобы изменить ширину ваших изображений по умолчанию.

from PIL import Image

basewidth = 300
img = Image.open('somepic.jpg')
wpercent = (basewidth/float(img.size[0]))
hsize = int((float(img.size[1])*float(wpercent)))
img = img.resize((basewidth,hsize), Image.ANTIALIAS)
img.save('sompic.jpg') 
54 голосов
/ 02 июня 2009

Я также рекомендую использовать метод миниатюр PIL, потому что он удаляет из вас все проблемы с соотношением.

Один важный совет: замените

im.thumbnail(size)

с

im.thumbnail(size,Image.ANTIALIAS)

по умолчанию, PIL использует фильтр Image.NEAREST для изменения размера, что приводит к хорошей производительности, но низкому качеству.

26 голосов
/ 14 мая 2015

Основываясь на @tomvon, я закончил использовать следующее:

Ширина изменения размера:

new_width  = 680
new_height = new_width * height / width 

Изменение размера:

new_height = 680
new_width  = new_height * width / height

Тогда просто:

img = img.resize((new_width, new_height), Image.ANTIALIAS)
18 голосов
/ 04 октября 2012

PIL уже имеет возможность обрезать изображение

img = ImageOps.fit(img, size, Image.ANTIALIAS)
16 голосов
/ 16 марта 2016
from PIL import Image

img = Image.open('/your iamge path/image.jpg') # image extension *.png,*.jpg
new_width  = 200
new_height = 300
img = img.resize((new_width, new_height), Image.ANTIALIAS)
img.save('output image name.png') # format may what u want ,*.png,*jpg,*.gif
11 голосов
/ 13 декабря 2008

Если вы пытаетесь сохранить такое же соотношение сторон, то не измените ли вы размер в процентах от исходного размера?

Например, половина оригинального размера

half = 0.5
out = im.resize( [int(half * s) for s in im.size] )
3 голосов
/ 27 сентября 2015
from PIL import Image
from resizeimage import resizeimage

def resize_file(in_file, out_file, size):
    with open(in_file) as fd:
        image = resizeimage.resize_thumbnail(Image.open(fd), size)
    image.save(out_file)
    image.close()

resize_file('foo.tif', 'foo_small.jpg', (256, 256))

Я использую эту библиотеку:

pip install python-resize-image
2 голосов
/ 22 января 2019

Я пытался изменить размер некоторых изображений для видео в режиме слайд-шоу, и поэтому я хотел не только одно максимальное измерение, но и максимальную ширину и максимальную высоту (размер видеокадра).
И всегда была возможность портретного видео ...
Метод Image.thumbnail был многообещающим, но я не смог сделать его более масштабным.

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

from PIL import Image

def get_resized_img(img_path, video_size):
    img = Image.open(img_path)
    width, height = video_size  # these are the MAX dimensions
    video_ratio = width / height
    img_ratio = img.size[0] / img.size[1]
    if video_ratio >= 1:  # the video is wide
        if img_ratio <= video_ratio:  # image is not wide enough
            width_new = int(height * img_ratio)
            size_new = width_new, height
        else:  # image is wider than video
            height_new = int(width / img_ratio)
            size_new = width, height_new
    else:  # the video is tall
        if img_ratio >= video_ratio:  # image is not tall enough
            height_new = int(width / img_ratio)
            size_new = width, height_new
        else:  # image is taller than video
            width_new = int(height * img_ratio)
            size_new = width_new, height
    return img.resize(size_new, resample=Image.LANCZOS)
2 голосов
/ 31 мая 2018

Простой метод для сохранения ограниченных соотношений и передачи максимальной ширины / высоты. Не самая красивая, но выполняет свою работу и легко понять:

def resize(img_path, max_px_size, output_folder):
    with Image.open(img_path) as img:
        width_0, height_0 = img.size
        out_f_name = os.path.split(img_path)[-1]
        out_f_path = os.path.join(output_folder, out_f_name)

        if max((width_0, height_0)) <= max_px_size:
            print('writing {} to disk (no change from original)'.format(out_f_path))
            img.save(out_f_path)
            return

        if width_0 > height_0:
            wpercent = max_px_size / float(width_0)
            hsize = int(float(height_0) * float(wpercent))
            img = img.resize((max_px_size, hsize), Image.ANTIALIAS)
            print('writing {} to disk'.format(out_f_path))
            img.save(out_f_path)
            return

        if width_0 < height_0:
            hpercent = max_px_size / float(height_0)
            wsize = int(float(width_0) * float(hpercent))
            img = img.resize((max_px_size, wsize), Image.ANTIALIAS)
            print('writing {} to disk'.format(out_f_path))
            img.save(out_f_path)
            return

Вот скрипт python , который использует эту функцию для запуска изменения размера изображения пакета.

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