将目录中的多个不同图像组合成 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
我迭代了一个目录的图像。我想从这些图像中创建一个 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