如何使用 PIL/Pillow 将图像合并到画布中?

Posted

技术标签:

【中文标题】如何使用 PIL/Pillow 将图像合并到画布中?【英文标题】:How do you merge images into a canvas using PIL/Pillow? 【发布时间】:2012-05-25 17:08:14 【问题描述】:

我不熟悉 PIL,但我知道在 ImageMagick 中将一堆图像放入一个网格中非常容易。

例如,我如何将 16 张图像放入一个 4×4 的网格中,我可以在其中指定行和列之间的间距?

【问题讨论】:

【参考方案1】:

扩展了 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)

【讨论】:

嗨。你的答案看起来很棒。你知道如何避免图片边缘的黑线吗? @IrbinB。当我写这篇文章时,我希望图像之间的划分清晰,所以我包括了水平和垂直填充(黑线)。垂直填充由代码中的 padding 参数给出,因此只需将其设置为 0 即可删除它们。水平填充不小心被硬编码了,我离开它是因为我想要那种效果。我必须尝试找出如何删除水平填充;每个循环都会有 1 个像素的偏差。 感谢您的回复。当然,我意识到 padding 参数但将其设置为 0 对我不起作用。奇怪的是,我的最终图像中只出现了垂直填充。也许我应该提出一个新问题。 @IrbinB。尝试将:scaled_img_height = ceil(img_height*sf) 更改为 scaled_img_height = floor(img_height*sf)。那应该删除水平线。例如,我将同一张图片(imgur.com/a/AtyrAR5)复制了 30 张,并将它们输入到更改后的程序中,得到:imgur.com/a/kbdga0G 它没有用。但我已经解决了我的问题。我发现问题与我的图像文件有关。所以,你的代码没有问题。谢谢。【参考方案2】:

这在PIL 中也很容易做到。创建一个空图像,然后使用paste 将您想要的图像粘贴到您需要的任何位置。这是一个简单的例子:

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()

【讨论】:

以上是关于如何使用 PIL/Pillow 将图像合并到画布中?的主要内容,如果未能解决你的问题,请参考以下文章

PIL和Pillow

提交带有表格的图像时需要Django Pillow或Pil吗?

Python图像处理库Pillow常用使用方法

python 使用zbar,cv2和PIL / Pillow扫描图像中的条形码。

cv2 & PIL(pillow)显示图像

PIL(Pillow)的学习笔记