Skip to content

Bilder verketten mit Python, Pillow

Python

Pillow (PIL) can used Werden, um mehrere Bilder vertikal und horizontal zu verketten (kombinieren). Erstellen Sie einen Hintergrund mit Image.new() und fügen Sie die Bilder mit Image.paste() ein.

Es gibt mehrere Möglichkeiten, Bilder unterschiedlicher Größe zu verketten.

Dieser Artikel sterben folgende Fälle.

  • Bilder mit gleicher Höhe oder Breite verketten
  • Verketten Sie Bilder mit unterschiedlichen Höhen oder Breiten
    • Extrabereich ausschneiden und verketten
    • Machen Sie Ränder und verketten Sie
    • Größe ändern und verketten
  • Verketten Sie mehrere Bilder auf einmal
  • Verketten Sie dasselbe Bild wiederholt

Verwenden Sie die folgenden zwei Bilder als Beispiel.

from PIL import Image

im1 = Image.open('data/src/lena.jpg')
im2 = Image.open('data/src/rocket.jpg')

Es WIRD davon ausgegangen, dass der Beispielcode ein Farbbild ist (mode=“RGB“), aber der Ablauf IST derselbe für monochrome Bilder (mode=“L“).

Weitere Informationen zur Bildverkettung mit OpenCV und scikit-image finden SIE in den following Artikeln. Für Bilder gleicher Größe ist scikit-image einfach zu verwenden. Sie können auch einen Rahmen zwischen den Bildern hinzufügen.

Bilder mit gleicher Höhe oder Breite verketten

Erstellen Sie einen Hintergrund mit Image.new() und fügen Sie die Bilder mit Image.paste() ein.

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')

Pythonkissen concat h

Pythonkissen concat v

Extrabereich ausschneiden und verketten

In Image.paste() wird der Bereich außerhalb des einzufügenden Bildbereichs ignoriert (ausgeschnitten).

Bei horizontaler Ausrichtung einen Hintergrund mit geringerer Höhe und bei vertikaler Ausrichtung mit geringerer Breite erzeugen, WIRD überschüssige Fläche abgeschnitten und verkettet.

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-Kissen concat h-Schnitt

Python-Kissen Concat V-Schnitt

Im obigen Beispiel WIRD der obere oder linke Rand jedes Bilds ausgerichtet. Die Fäustlinge können auch ausgerichtet werden.

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')

pythonkissen concat h schnitt mitte

Pythonkissen concat v Schnittmitte

Machen Sie Ränder und verketten Sie

Erstellen Sie Ränder und verketten Sie, um zu verhindern, dass das Originalbild abgeschnitten WIRD.

Erstellen Sie zuerst einen großen Hintergrund. Sie können den Rand in einer beliebigen Farbe gestalten, indem Sie den Parameter color von Image.new() angeben.

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')

Pythonkissen concat h leer

Pythonkissen concat v leer

Größe ändern und verketten

Passen Sie die Größe des Bildes an die Breite oder Höhe an und verbinden Sie sie.

Im Beispiel kann ausgewählt Werden, ob ein großes Bild klein oder ein kleines Bild groß skaliert werden soll. Grundsätzlich ist es besser, die Größe eines großen Bildes auf eine kleinere Größe zu reduzieren, da die Bildqualität bei einer Vergrößerung abnimmt.

Außerdem kann der Filter für das Resampling angegeben werden.

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-Kissen Concat h Größe ändern

Python Pillow Concat v Größenänderung

Verketten Sie mehrere Bilder auf einmal

Mit der oben definierbaren Funktion can SIE ein verkettetes Bild erhalten, in dem mehrere Bilder vertikal und horizontal in einer Reihe angeordnet sind.

Übergeben Sie beispielsweise eine Liste von PIL.Image und verketten Sie sie vertikal und horizontal.

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')

Pythonkissen concat h multi blank

Im Beispiel Beispiel verwenden wir sterben Funktion, um Ränder zu erstellen. Wenn Sie mit anderen Möglichkeiten verketten möchten, verwenden Sie die entsprechende Funktion entsprechend.

Wenn Sie mehrere Bilder in der Größe ändern und anordnen, ist es besser, zuerst alle Bilder auf die endgültige Breite oder Höhe zu skalieren, um eine wiederholte Größenänderung und eine Beeinträchtigung der Bildqualität zu vermeiden.

Erstellen Sie hier zunächst einen großen Hintergrund mit 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-Kissen Concat h Multi Resize

Python Pillow Concat v Multi-Größenänderung

Auch die Funktion zum Anordnen in einer Kachel ist einfach. Übergeben Sie eine 2D-Liste von PIL.Image und ordnen Sie sie vertikal und horizontal in Kacheln an.

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')

Größe der Python-Kissen-Concat-Fliese ändern

Listenverständnisse werden used, um Eine in der Größe angepasste Bildliste zu erstellen und die Mindestbreite und -höhe sowie die Gesamtbreite und -höhe zu berechnen.

Verketten Sie dasselbe Bild wiederholt

Wenn Sie dasselbe Bild wiederholt vertikal und horizontal kombinieren möchten, ist die Angabe in der 2D-Liste mühsam, daher ist es bequem, eine Funktion zum Festlegen der Anzahl der Wiederholungen aufzurufen.

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-Kissen Concat-Fliesenwiederholung