如何使用Pillow连接图像 ?Pillow (PIL) 可用于垂直和水平连接(组合)多个图像。创建背景
Image.new()
并使用 粘贴图像
Image.paste()
。
python如何横向拼接图片 ?有多种方法可以连接不同大小的图像以及实现python横向拼接图片。
本文介绍以下案例。
连接具有相同高度或宽度的图像
连接具有不同高度或宽度的图像
剪切额外区域并连接
制作边距并连接
调整大小并连接
一次连接多个图像
重复连接相同的图像
以下面两张图片为例。
from PIL import Image
im1 = Image.open('data/src/lena.jpg')
im2 = Image.open('data/src/rocket.jpg')
示例代码假定为彩色图像 (
mode='RGB'
),但流程与黑白图像 (
mode='L'
)相同。
有关使用 OpenCV 和 scikit-image 进行图像连接的更多信息,请参阅以下文章。对于相同大小的图像,scikit-image 易于使用。你还可以在图像之间添加边框。
使用 Python、OpenCV(hconcat、vconcat、np.tile)连接图像
使用 Python 创建蒙太奇图像,scikit-image (skimage.util.montage)
连接具有相同高度或宽度的图像
创建背景
Image.new()
并使用 粘贴图像
Image.paste()
。
def get_concat_h(im1, im2):
dst = Image.new('RGB', (im1.width + im2.width, im1.height))
dst.paste(im1, (0, 0))
dst.paste(im2, (im1.width, 0))
return dst
def get_concat_v(im1, im2):
dst = Image.new('RGB', (im1.width, im1.height + im2.height))
dst.paste(im1, (0, 0))
dst.paste(im2, (0, im1.height))
return dst
get_concat_h(im1, im1).save('data/dst/pillow_concat_h.jpg')
get_concat_v(im1, im1).save('data/dst/pillow_concat_v.jpg')
python横向拼接图片:剪切额外区域并连接
在 中
Image.paste()
,超出要粘贴图像范围的区域将被忽略(剪切)。
在水平对齐的情况下,生成一个高度较小的背景,在垂直对齐的情况下,生成一个较小的宽度,多余的区域被剪切和连接。
def get_concat_h_cut(im1, im2):
dst = Image.new('RGB', (im1.width + im2.width, min(im1.height, im2.height)))
dst.paste(im1, (0, 0))
dst.paste(im2, (im1.width, 0))
return dst
def get_concat_v_cut(im1, im2):
dst = Image.new('RGB', (min(im1.width, im2.width), im1.height + im2.height))
dst.paste(im1, (0, 0))
dst.paste(im2, (0, im1.height))
return dst
get_concat_h_cut(im1, im2).save('data/dst/pillow_concat_h_cut.jpg')
get_concat_v_cut(im1, im2).save('data/dst/pillow_concat_v_cut.jpg')
在上面的示例中,每个图像的顶部或左侧边缘对齐。中心也可以对齐。
def get_concat_h_cut_center(im1, im2):
dst = Image.new('RGB', (im1.width + im2.width, min(im1.height, im2.height)))
dst.paste(im1, (0, 0))
dst.paste(im2, (im1.width, (im1.height - im2.height) // 2))
return dst
def get_concat_v_cut_center(im1, im2):
dst = Image.new('RGB', (min(im1.width, im2.width), im1.height + im2.height))
dst.paste(im1, (0, 0))
dst.paste(im2, ((im1.width - im2.width) // 2, im1.height))
return dst
get_concat_h_cut_center(im1, im2).save('data/dst/pillow_concat_h_cut_center.jpg')
get_concat_v_cut_center(im1, im2).save('data/dst/pillow_concat_v_cut_center.jpg')
制作边距并连接
如何使用Pillow连接图像 ?留出边距并串联起来,防止原图被剪切。
首先创建一个大背景。你可以通过指定的参数做任何颜色的余量
color
的
Image.new()
。
def get_concat_h_blank(im1, im2, color=(0, 0, 0)):
dst = Image.new('RGB', (im1.width + im2.width, max(im1.height, im2.height)), color)
dst.paste(im1, (0, 0))
dst.paste(im2, (im1.width, 0))
return dst
def get_concat_v_blank(im1, im2, color=(0, 0, 0)):
dst = Image.new('RGB', (max(im1.width, im2.width), im1.height + im2.height), color)
dst.paste(im1, (0, 0))
dst.paste(im2, (0, im1.height))
return dst
get_concat_h_blank(im1, im2).save('data/dst/pillow_concat_h_blank.jpg')
get_concat_v_blank(im1, im2, (0, 64, 128)).save('data/dst/pillow_concat_v_blank.jpg')
调整大小并连接
python如何横向拼接图片 ?调整图像大小以匹配宽度或高度并将它们连接起来。
在示例中,可以选择是将大图像调整为小还是将小图像调整为大。基本上,将大图像的尺寸缩小到较小的尺寸会更好,因为图像放大时图像质量会下降。
此外,可以指定用于重采样的过滤器。
def get_concat_h_resize(im1, im2, resample=Image.BICUBIC, resize_big_image=True):
if im1.height == im2.height:
_im1 = im1
_im2 = im2
elif (((im1.height > im2.height) and resize_big_image) or
((im1.height < im2.height) and not resize_big_image)):
_im1 = im1.resize((int(im1.width * im2.height / im1.height), im2.height), resample=resample)
_im2 = im2
else:
_im1 = im1
_im2 = im2.resize((int(im2.width * im1.height / im2.height), im1.height), resample=resample)
dst = Image.new('RGB', (_im1.width + _im2.width, _im1.height))
dst.paste(_im1, (0, 0))
dst.paste(_im2, (_im1.width, 0))
return dst
def get_concat_v_resize(im1, im2, resample=Image.BICUBIC, resize_big_image=True):
if im1.width == im2.width:
_im1 = im1
_im2 = im2
elif (((im1.width > im2.width) and resize_big_image) or
((im1.width < im2.width) and not resize_big_image)):
_im1 = im1.resize((im2.width, int(im1.height * im2.width / im1.width)), resample=resample)
_im2 = im2
else:
_im1 = im1
_im2 = im2.resize((im1.width, int(im2.height * im1.width / im2.width)), resample=resample)
dst = Image.new('RGB', (_im1.width, _im1.height + _im2.height))
dst.paste(_im1, (0, 0))
dst.paste(_im2, (0, _im1.height))
return dst
get_concat_h_resize(im1, im2).save('data/dst/pillow_concat_h_resize.jpg')
get_concat_v_resize(im1, im2, resize_big_image=False).save('data/dst/pillow_concat_v_resize.jpg')
python横向拼接图片:一次连接多个图像
你可以使用上面定义的函数获得一个串联图像,其中多个图像在垂直和水平方向上排列成一行。
例如,传递一个列表
PIL.Image
并将它们垂直和水平连接起来。
def get_concat_h_multi_blank(im_list):
_im = im_list.pop(0)
for im in im_list:
_im = get_concat_h_blank(_im, im)
return _im
get_concat_h_multi_blank([im1, im2, im1]).save('data/dst/pillow_concat_h_multi_blank.jpg')
在上面的例子中,我们使用函数来制作边距。如果要与其他方式连接,请酌情使用相应的函数。
如何使用Pillow连接图像?调整大小和排列多张图像时,最好先将所有图像调整为最终的宽度或高度,以防止重复调整大小和图像质量下降。
在这里,首先创建一个大背景
Image.new()
。
def get_concat_h_multi_resize(im_list, resample=Image.BICUBIC):
min_height = min(im.height for im in im_list)
im_list_resize = [im.resize((int(im.width * min_height / im.height), min_height),resample=resample)
for im in im_list]
total_width = sum(im.width for im in im_list_resize)
dst = Image.new('RGB', (total_width, min_height))
pos_x = 0
for im in im_list_resize:
dst.paste(im, (pos_x, 0))
pos_x += im.width
return dst
def get_concat_v_multi_resize(im_list, resample=Image.BICUBIC):
min_width = min(im.width for im in im_list)
im_list_resize = [im.resize((min_width, int(im.height * min_width / im.width)),resample=resample)
for im in im_list]
total_height = sum(im.height for im in im_list_resize)
dst = Image.new('RGB', (min_width, total_height))
pos_y = 0
for im in im_list_resize:
dst.paste(im, (0, pos_y))
pos_y += im.height
return dst
get_concat_h_multi_resize([im1, im2, im1]).save('data/dst/pillow_concat_h_multi_resize.jpg')
get_concat_v_multi_resize([im1, im2, im1]).save('data/dst/pillow_concat_v_multi_resize.jpg')
python如何横向拼接图片?排列在瓷砖中的功能也很容易。传递 的 2D 列表
PIL.Image
,并在垂直和水平方向的平铺中排列。
def get_concat_tile_resize(im_list_2d, resample=Image.BICUBIC):
im_list_v = [get_concat_h_multi_resize(im_list_h, resample=resample) for im_list_h in im_list_2d]
return get_concat_v_multi_resize(im_list_v, resample=resample)
get_concat_tile_resize([[im1],
[im1, im2],
[im1, im2, im1]]).save('data/dst/pillow_concat_tile_resize.jpg')
列表推导用于创建调整大小的图像列表并计算最小宽度和高度、总宽度和高度。
python横向拼接图片:重复连接相同的图像
如果要纵向和横向重复组合相同的图像,在2D列表中指定很麻烦,因此可以方便地准备一个函数来指定重复次数。
def get_concat_h_repeat(im, column):
dst = Image.new('RGB', (im.width * column, im.height))
for x in range(column):
dst.paste(im, (x * im.width, 0))
return dst
def get_concat_v_repeat(im, row):
dst = Image.new('RGB', (im.width, im.height * row))
for y in range(row):
dst.paste(im, (0, y * im.height))
return dst
def get_concat_tile_repeat(im, row, column):
dst_h = get_concat_h_repeat(im, column)
return get_concat_v_repeat(dst_h, row)
im_s = im1.resize((im1.width // 2, im1.height // 2))
get_concat_tile_repeat(im_s, 3, 4).save('data/dst/pillow_concat_tile_repeat.jpg')