Python PIL - 在数组中连接图像

时间:2015-10-20 19:01:50

标签: python image python-imaging-library

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

Python 2.7.10

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

enter image description here

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

现在,我不知道为什么在图像的右下方出现几条像素宽的黑线。请让我知道为什么会这样,以及如何解决这个问题。

2 个答案:

答案 0 :(得分:2)

答案很简单:你不能将1024除以10,你将得到4个像素。

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

>>> 1024 / 10
102

要解决您的问题,您有两种选择:

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

  2. 如果您对黑色衬垫通常没问题,只需在左右和上下边缘使它们相等。

答案 1 :(得分:0)

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

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

最后,我删除了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))