将目录中的多个不同图像组合成 canvas 大小的 3x6

Combine multiple different images from a directory into a canvas sized 3x6

我迭代了一个目录的图像。我想从这些图像中创建一个 3x6 canvas,一个新图像,它将并排显示该目录的图像到单个图像/canvas。每个图像必须是不同的图像。并排。 –

我有以下代码。它尝试从存储在列表中的目录中读取图像文件名。然后它尝试将每个图像复制/组合成 3x6 canvas。然而,我想要的结果并没有发生。 我做错了什么?

import Image
import os
import PIL
import glob
import matplotlib.pyplot as plt

# path
path = "/media/"
listing = os.listdir(path)

# getting all path+filename in a list
npath=[]
im=[]
for infile in listing:
  im.append(infile)
  npath.append(os.path.join(path, infile))

#creates a new empty image, RGB mode, and size 400 by 400.
new_im = Image.new('RGB', (2100,2400))


#Here I resize my opened image, so it is no bigger than ****
#Iterate through a grid with some spacing, to place my image
for i in xrange(0,2100,700):
    for j in xrange(0,2400, 400):
        for imagefile in npath:
            im=Image.open(imagefile)
            im.thumbnail((1000,1000))
            #paste the image at location i,j:
            new_im.paste(im, (i,j))
            new_im.show()
#saving
new_im.save('/media/test.png')

解决方案

import Image
import os
import PIL
import glob
import matplotlib.pyplot as plt

# path
path = "/media/"
listing = os.listdir(path)


# getting all path+filename in a list
npath=[]
im=[]

for infile in listing:
  im.append(infile)
  npath.append(os.path.join(path, infile))

#creates a new empty image, RGB mode, and size 400 by 400.
new_im = Image.new('RGB', (2500,3000))

for i in xrange(0,2500,800):
    for j in xrange(0,3000, 500):
        im=Image.open(npath.pop(0))
        im.thumbnail((1000,1000))
        #paste the image at location i,j:
        new_im.paste(im, (i,j))
    new_im.save('/media/test.png')

不要为每个位置遍历图像列表,而是使用列表:

for i in xrange(0, 2100, 700):
    for j in xrange(0, 2400, 400):
        try:
            filepath = npath.pop(0)
        except IndexError:
            break
        im = Image.open(filepath)
        im.thumbnail((1000,1000))
        # paste the image at location i,j
        new_im.paste(im, (i,j))
    else:
        continue  # executed if inner loop ended normally (no break)
    break  # executed if 'continue' was skipped (break occurred)

我认为您尝试做的事情可以通过使用 PEP 342 — Coroutines via Enhanced Generators 中描述的协程以非常普遍的方式解决。下面是处理创建和布局缩略图到任何大小的网格的代码。它可能会生成多个缩略图页面,具体取决于有多少图像以及在网格填满之前适合网格的图像数量。

我试图避免使用硬编码数字来增加其灵活性。缩略图大小和网格布局现在都是变量。

注意: 所有实际创建和保存缩略图输出图像的调用都被注释掉了,所以在测试中方便快捷运行模式。您需要取消注释它们才能真正让它产生任何输出图像。

from glob import iglob
from PIL import Image
import os

def thumbnailer(thumbpath, grid, thumb_size, background_color):
    """ Coroutine to receive image file names and produce thumbnail pages of
        them laid-out in a grid.
    """
    page_num = 0
    page_extent = grid[0]*thumb_size[0], grid[1]*thumb_size[1]

    try:
        while True:
            paste_cnt = 0
            #new_img = Image.new('RGB', page_extent, background_color)
            for x in xrange(0, page_extent[0], thumb_size[0]):
                for y in xrange(0, page_extent[1], thumb_size[1]):
                    try:
                        filepath = (yield)
                    except GeneratorExit:
                        print('GeneratorExit received')
                        return

                    filename = os.path.basename(filepath)
                    print('{} thumbnail -> ({}, {})'.format(filename, x, y))
                    #thumbnail_img = Image.open(filepath)
                    #thumbnail_img.thumbnail(thumb_size)
                    #new_img.paste(thumbnail_img, (x,y))
                    paste_cnt += 1
                else:
                    continue  # no break, continue outer loop
                break  # break occurred, terminate outer loop

            print('====> thumbnail page completed')
            if paste_cnt:
                page_num += 1
                print('Saving thumbpage{}.png'.format(page_num))
                #img.save(
                #    os.path.join(thumbpath, 'thumbpage{}.png'.format(page_num)))
    finally:
        print('====> finally')
        if paste_cnt:
            page_num += 1
            print('Saving thumbpage{}.png'.format(page_num))
            #img.save(
            #    os.path.join(thumbpath, 'thumbpage{}.png'.format(page_num)))

path = '/media'
#npath = [infile for infile in iglob(os.path.join(path, '*.png'))]
npath = ['image{}.png'.format(i) for i in xrange(1, 37+1)]  # test names

coroutine = thumbnailer(path, (3,6), (1000,1000), 'white')
coroutine.next()  # start it

for filepath in npath:
    coroutine.send(filepath)

print('====> closing coroutine')
coroutine.close()

这是上面的输出,它从布置在 3x6 网格上的 37 个虚拟图像文件生成 3 个缩略图页面:

image1.png thumbnail -> (0, 0)
image2.png thumbnail -> (0, 1000)
image3.png thumbnail -> (0, 2000)
image4.png thumbnail -> (0, 3000)
image5.png thumbnail -> (0, 4000)
image6.png thumbnail -> (0, 5000)
image7.png thumbnail -> (1000, 0)
image8.png thumbnail -> (1000, 1000)
image9.png thumbnail -> (1000, 2000)
image10.png thumbnail -> (1000, 3000)
image11.png thumbnail -> (1000, 4000)
image12.png thumbnail -> (1000, 5000)
image13.png thumbnail -> (2000, 0)
image14.png thumbnail -> (2000, 1000)
image15.png thumbnail -> (2000, 2000)
image16.png thumbnail -> (2000, 3000)
image17.png thumbnail -> (2000, 4000)
image18.png thumbnail -> (2000, 5000)
====> thumbnail page completed
Saving thumbpage1.png
image19.png thumbnail -> (0, 0)
image20.png thumbnail -> (0, 1000)
image21.png thumbnail -> (0, 2000)
image22.png thumbnail -> (0, 3000)
image23.png thumbnail -> (0, 4000)
image24.png thumbnail -> (0, 5000)
image25.png thumbnail -> (1000, 0)
image26.png thumbnail -> (1000, 1000)
image27.png thumbnail -> (1000, 2000)
image28.png thumbnail -> (1000, 3000)
image29.png thumbnail -> (1000, 4000)
image30.png thumbnail -> (1000, 5000)
image31.png thumbnail -> (2000, 0)
image32.png thumbnail -> (2000, 1000)
image33.png thumbnail -> (2000, 2000)
image34.png thumbnail -> (2000, 3000)
image35.png thumbnail -> (2000, 4000)
image36.png thumbnail -> (2000, 5000)
====> thumbnail page completed
Saving thumbpage2.png
image37.png thumbnail -> (0, 0)
====> closing coroutine
GeneratorExit received
====> finally
Saving thumbpage3.png