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
要解决你的问题,你有两个选择:
根据行数和列数动态调整大小。例如,将 10 列的宽度从 1024 减少到 1020。
如果您通常对黑色填充没问题,只需让它们在左右和上下边缘相等即可。
好的,我已经解决了我的问题,感谢 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))
编辑:我更改了标题,以便人们更容易在下面的答案中找到这个有用的代码。 :)
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
要解决你的问题,你有两个选择:
根据行数和列数动态调整大小。例如,将 10 列的宽度从 1024 减少到 1020。
如果您通常对黑色填充没问题,只需让它们在左右和上下边缘相等即可。
好的,我已经解决了我的问题,感谢 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))