使用 Python 水平组合多个图像

新手上路,请多包涵

我正在尝试在 Python 中水平组合一些 JPEG 图像。

问题

我有 3 张图片 - 每张都是 148 x 95 - 见附件。我刚刚制作了同一张图片的 3 个副本 - 这就是它们相同的原因。

在此处输入图像描述在此处输入图像描述在此处输入图像描述

我的尝试

我正在尝试使用以下代码水平加入它们:

 import sys
from PIL import Image

list_im = ['Test1.jpg','Test2.jpg','Test3.jpg']

# creates a new empty image, RGB mode, and size 444 by 95
new_im = Image.new('RGB', (444,95))

for elem in list_im:
    for i in xrange(0,444,95):
        im=Image.open(elem)
        new_im.paste(im, (i,0))
new_im.save('test.jpg')

但是,这会产生附加的输出 test.jpg

在此处输入图像描述

问题

有没有办法水平连接这些图像,使 test.jpg 中的子图像不显示额外的部分图像?

附加信息

我正在寻找一种水平连接 n 图像的方法。我想一般地使用此代码,所以我更愿意:

  • 如果可能,不要硬编码图像尺寸
  • 在一行中指定尺寸,以便可以轻松更改

原文由 edesz 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 467
2 个回答

你可以这样做:

 import sys
from PIL import Image

images = [Image.open(x) for x in ['Test1.jpg', 'Test2.jpg', 'Test3.jpg']]
widths, heights = zip(*(i.size for i in images))

total_width = sum(widths)
max_height = max(heights)

new_im = Image.new('RGB', (total_width, max_height))

x_offset = 0
for im in images:
  new_im.paste(im, (x_offset,0))
  x_offset += im.size[0]

new_im.save('test.jpg')

Test1.jpg

测试1.jpg

Test2.jpg

测试2.jpg

Test3.jpg

测试3.jpg

test.jpg

在此处输入图像描述


嵌套的 for i in xrange(0,444,95): 将每个图像粘贴 5 次,间隔 95 像素。每个外循环迭代粘贴在前一个上。

 for elem in list_im:
  for i in xrange(0,444,95):
    im=Image.open(elem)
    new_im.paste(im, (i,0))
  new_im.save('new_' + elem + '.jpg')

在此处输入图像描述在此处输入图像描述在此处输入图像描述

原文由 dting 发布,翻译遵循 CC BY-SA 4.0 许可协议

我会试试这个:

 import numpy as np
import PIL
from PIL import Image

list_im = ['Test1.jpg', 'Test2.jpg', 'Test3.jpg']
imgs    = [ Image.open(i) for i in list_im ]
# pick the image which is the smallest, and resize the others to match it (can be arbitrary image shape here)
min_shape = sorted( [(np.sum(i.size), i.size ) for i in imgs])[0][1]
imgs_comb = np.hstack([i.resize(min_shape) for i in imgs])

# save that beautiful picture
imgs_comb = Image.fromarray( imgs_comb)
imgs_comb.save( 'Trifecta.jpg' )

# for a vertical stacking it is simple: use vstack
imgs_comb = np.vstack([i.resize(min_shape) for i in imgs])
imgs_comb = Image.fromarray( imgs_comb)
imgs_comb.save( 'Trifecta_vertical.jpg' )

只要所有图像都具有相同的种类(所有 RGB、所有 RGBA 或所有灰度),它就应该工作。通过多几行代码来确保这种情况应该不难。这是我的示例图像和结果:

测试1.jpg

测试1.jpg

测试2.jpg

测试2.jpg

测试3.jpg

测试3.jpg

三连胜.jpg:

组合图像

Trifecta_vertical.jpg

在此处输入图像描述

原文由 dermen 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题