Python PIL - 将图像连接到数组中

Python PIL - Joining images in an array

编辑:我更改了标题,以便人们更容易在下面的答案中找到这个有用的代码。 :)

Python 2.7.10

我有这个脚本,它应该在文件夹中拍摄一堆图像(名为图像 001、图像 002、图像 003 等)并将它们拼接成更少的图像。这是一个 10 x 10 输出图像的示例(来自 Biggie Smalls 的音乐视频 "Juicy" 的前 100 帧 @10FPS):

import Image
import glob
import sys
name = raw_input('What is the file name (excluding the extension) of your video that was converted using FreeVideoToJPGConverter?\n')
rows = int(raw_input('How many rows do you want?\n'))
columns = int(raw_input('How many columns do you want?\n'))
images = glob.glob('../' + name + '*.jpg')
new_im = Image.new('RGB', (1024,1024))
x_cntr = 0 #X counter
y_cntr = 0 #Y counter
for x in xrange(0,len(images),1):
    if x%(rows*columns) == 0: #if the new image is filled, save it in output and create new one
        new_im.save('Output' + str(x) + '.jpg')
        new_im = Image.new('RGB', (1024,1024))
        y_cntr = 0
        x_cntr = 0
    elif x%rows == 0: #Else if a new row is completed, then go back to 0 on a new row
        x_cntr = 0
        y_cntr = y_cntr + 1024/columns
    elif x%1 == 0: #If no new row or image is complete, just add another image to the current row
        x_cntr = x_cntr + 1024/rows
    im = Image.open(images[x])
    im = im.resize((1024/rows, 1024/columns), Image.ANTIALIAS)
    new_im.paste(im, (x_cntr, y_cntr))
    sys.stdout.write("\r%d%%" % x/len(images))
    sys.stdout.flush()

现在,我不知道为什么图像的右侧和底部会出现一条几像素宽的黑线。请告诉我这是为什么以及如何解决这个问题。

答案很简单:不能将 1024 除以 10,还剩 4 个像素。

在Python2中,如果操作数是整数,则除法是截断的:

>>> 1024 / 10
102

要解决你的问题,你有两个选择:

  1. 根据行数和列数动态调整大小。例如,将 10 列的宽度从 1024 减少到 1020。

  2. 如果您通常对黑色填充没问题,只需让它们在左右和上下边缘相等即可。

好的,我已经解决了我的问题,感谢 alexanderlukanin13 发现了这个问题。我基本上将 1024/10 更改为 1024/10 + 1024%10 以便添加其余部分。这甚至适用于奇数分辨率(如 3x3 或 7x7 等)。

我还为您的分辨率选择添加了输入。它最初设置为 1024x1024,因为一个名为 Roblox 的网站在上传图像时会自动将图像限制为 1024x1024。

最后,我删除了 sys 打印完成百分比的方式,因为我不需要它 print 可用。我尝试使用 sys 的唯一原因是用百分比自动更新一行而不是打印一个新行。我一直不知道该怎么做,但这并不重要。

所以这是工作代码:

import Image
import glob
name = raw_input('What is the file name (excluding the extension) of your video that was converted using FreeVideoToJPGConverter?\n')
x_res = int(raw_input('What do you want the height of your image to be (in pixels)?\n'))
y_res = int(raw_input('What do you want the width of your image to be (in pixels)?\n'))
rows = int(raw_input('How many rows do you want?\n'))
columns = int(raw_input('How many columns do you want?\n'))
images = glob.glob('../' + name + '*.jpg')
new_im = Image.new('RGB', (x_res,y_res))
x_cntr = 0
y_cntr = 0
for x in xrange(0,len(images),1):
    if x%(rows*columns) == 0:
        new_im.save('Output' + str(x) + '.jpg')
        new_im = Image.new('RGB', (x_res,y_res))
        y_cntr = 0
        x_cntr = 0
        print str(round(100*(float(x)/len(images)), 1)) + "% Complete"
    elif x%rows == 0:
        x_cntr = 0
        y_cntr = y_cntr + y_res/columns
    elif x%1 == 0:
        x_cntr = x_cntr + x_res/rows
    im = Image.open(images[x])
    im = im.resize((x_res/rows + x_res%rows, y_res/columns + y_res%columns), Image.ANTIALIAS)
    new_im.paste(im, (x_cntr, y_cntr))