python横向拼接图片:如何使用Pillow连接图像?

2021年11月7日19:38:05 发表评论 3,751 次浏览
如何使用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横向拼接图片:如何使用Pillow连接图像?
python横向拼接图片:如何使用Pillow连接图像?

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')
python横向拼接图片:如何使用Pillow连接图像?
python横向拼接图片:如何使用Pillow连接图像?
在上面的示例中,每个图像的顶部或左侧边缘对齐。中心也可以对齐。
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')
python横向拼接图片:如何使用Pillow连接图像?
python横向拼接图片:如何使用Pillow连接图像?

制作边距并连接

如何使用Pillow连接图像?留出边距并串联起来,防止原图被剪切。 首先创建一个大背景。你可以通过指定的参数做任何颜色的余量colorImage.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横向拼接图片:如何使用Pillow连接图像?
python横向拼接图片:如何使用Pillow连接图像?

调整大小并连接

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横向拼接图片:如何使用Pillow连接图像?
python横向拼接图片:如何使用Pillow连接图像?

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')
python横向拼接图片:如何使用Pillow连接图像?
在上面的例子中,我们使用函数来制作边距。如果要与其他方式连接,请酌情使用相应的函数。 如何使用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横向拼接图片:如何使用Pillow连接图像?
python横向拼接图片:如何使用Pillow连接图像?
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横向拼接图片:如何使用Pillow连接图像?
列表推导用于创建调整大小的图像列表并计算最小宽度和高度、总宽度和高度。
  • Python 中的列表推导式

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')
python横向拼接图片:如何使用Pillow连接图像?
木子山

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: