Как вы объединяете изображения в холст с помощью PIL/Pillow?

Я не знаком с PIL, но знаю, что в ImageMagick очень легко поместить кучу изображений в сетку.

Как мне, например, поместить 16 изображений в сетку 44, где я могу указать промежуток между строками и столбцами?


person pythonee    schedule 18.05.2012    source источник


Ответы (2)


Это легко сделать и в PIL. Создайте пустое изображение и просто вставьте нужные изображения в любые нужные вам позиции, используя вставить. Вот краткий пример:

import Image

#opens an image:
im = Image.open("1_tree.jpg")
#creates a new empty image, RGB mode, and size 400 by 400.
new_im = Image.new('RGB', (400,400))

#Here I resize my opened image, so it is no bigger than 100,100
im.thumbnail((100,100))
#Iterate through a 4 by 4 grid with 100 spacing, to place my image
for i in xrange(0,500,100):
    for j in xrange(0,500,100):
        #I change brightness of the images, just to emphasise they are unique copies.
        im=Image.eval(im,lambda x: x+(i+j)/30)
        #paste the image at location i,j:
        new_im.paste(im, (i,j))

new_im.show()

введите здесь описание изображения

person fraxel    schedule 18.05.2012

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

#Evan Russenberger-Rosica
#Create a Grid/Matrix of Images
import PIL, os, glob
from PIL import Image
from math import ceil, floor

PATH = r"C:\Users\path\to\images"

frame_width = 1920
images_per_row = 5
padding = 2

os.chdir(PATH)

images = glob.glob("*.png")
images = images[:30]                #get the first 30 images

img_width, img_height = Image.open(images[0]).size
sf = (frame_width-(images_per_row-1)*padding)/(images_per_row*img_width)       #scaling factor
scaled_img_width = ceil(img_width*sf)                   #s
scaled_img_height = ceil(img_height*sf)

number_of_rows = ceil(len(images)/images_per_row)
frame_height = ceil(sf*img_height*number_of_rows) 

new_im = Image.new('RGB', (frame_width, frame_height))

i,j=0,0
for num, im in enumerate(images):
    if num%images_per_row==0:
        i=0
    im = Image.open(im)
    #Here I resize my opened image, so it is no bigger than 100,100
    im.thumbnail((scaled_img_width,scaled_img_height))
    #Iterate through a 4 by 4 grid with 100 spacing, to place my image
    y_cord = (j//images_per_row)*scaled_img_height
    new_im.paste(im, (i,y_cord))
    print(i, y_cord)
    i=(i+scaled_img_width)+padding
    j+=1

new_im.show()
new_im.save("out.jpg", "JPEG", quality=80, optimize=True, progressive=True)

Коллаж

person Evan Rosica    schedule 06.01.2019
comment
Привет. Ваш ответ выглядит великолепно. Знаете ли вы, как избежать этих черных линий на границах изображений? - person Irbin B.; 14.02.2019
comment
@ИрбинБ. Когда я писал это, я хотел, чтобы разделение между изображениями было четким, поэтому я включил горизонтальные и вертикальные отступы (черные линии). Вертикальное заполнение задается аргументом заполнения в коде, поэтому просто установите для него значение 0, чтобы удалить их. Горизонтальный отступ был случайно жестко закодирован, и я оставил его, потому что хотел этого эффекта. Мне пришлось бы поэкспериментировать, чтобы узнать, как удалить горизонтальную прокладку; что-то просто на 1 пиксель каждый цикл. - person Evan Rosica; 14.02.2019
comment
Спасибо за ваш ответ. Конечно, я понял об аргументе заполнения, но установка его на 0 у меня не сработала. Любопытно, что в моем финальном изображении появляются только вертикальные отступы. Возможно, мне следует открыть новый вопрос. - person Irbin B.; 14.02.2019
comment
@ИрбинБ. попробуйте изменить: scaled_img_height = ceil(img_height*sf) на scaled_img_height = floor(img_height*sf). Это должно удалить горизонтальные линии. Например, я сделал 30 копий одной и той же картинки (imgur.com/a/AtyrAR5) и скормил их в измененную программу и получили: imgur.com/a/kbdga0G - person Evan Rosica; 14.02.2019
comment
Это не сработало. Но я уже решил свою проблему. Я обнаружил, что проблема связана с моим файлом изображения. Так что это не проблема с вашим кодом. Спасибо. - person Irbin B.; 15.02.2019
comment
Кажется, это не добавляет горизонтальное дополнение, если я вручную не добавляю значения в scaled_img_height - person Jake Ireland; 29.01.2021
comment
на самом деле, мне пришлось добавить padding к scaled_img_height: scaled_img_height = ceil(img_height * sf) + padding - person Jake Ireland; 29.01.2021