Python, Pillowで画像に別の画像を貼り付けるpaste

Posted: | Tags: Python, Pillow, 画像処理

Pythonの画像処理ライブラリPillow(PIL)のImageモジュールに、画像を貼り付けるメソッドpaste()が用意されている。

Pillow(PIL)のインストール、基本的な使い方などは以下の記事参照。

ここでは、paste()を使った画像の貼り付けについて以下の三通りを説明する。

  • 通常の貼り付け
  • 貼り付ける位置を指定
  • マスク画像を使用

PILからImageをインポートして、ベース(背景)となる画像と貼り付ける画像をそれぞれ開いておく。

ImageDrawImageFilterは最後に説明するマスク画像を設定する際に使用する。単純に貼り付けるだけなら省略してOK。

from PIL import Image, ImageDraw, ImageFilter

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

ベース画像 貼り付け画像

通常の貼り付け

ベース画像のpaste()メソッドの引数に貼り付ける画像を指定する。

デフォルトでは貼り付け画像の左上がベース画像の原点(左上)となる位置に貼り付けられる。

im1.paste(im2)
im1.save('data/dst/rocket_pillow_paste.jpg', quality=95)

Pillow Image.paste 結果画像

paste()メソッドではベース画像自体が上書きされるため、元の画像を残しておきたい場合はcopy()メソッドでコピーした画像を使う。

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

back_im = im1.copy()
back_im.paste(im2)
back_im.save('data/dst/rocket_pillow_paste.jpg', quality=95)

貼り付ける位置を指定

貼り付ける位置は、paste()メソッドの第二引数boxにタプル(左上のx座標, 左上のy座標)で指定する。

back_im = im1.copy()
back_im.paste(im2, (100, 50))
back_im.save('data/dst/rocket_pillow_paste_pos.jpg', quality=95)

Pillow Image.paste 結果画像 貼り付け位置指定

貼り付け画像がベース画像の領域外にはみ出す場合、はみ出した部分は無視される。

back_im = im1.copy()
back_im.paste(im2, (400, 100))
back_im.save('data/dst/rocket_pillow_paste_out.jpg', quality=95)

Pillow Image.paste 結果画像 貼り付け位置指定 領域外

マスク画像を使用

paste()メソッドの第三引数maskにマスク画像を指定すると、貼り付け画像を矩形だけでなく様々な形に切り抜いて貼り付けることができる。

マスク画像として使用できるのは、貼り付け画像と同じサイズでmodeが以下の三種類の場合。

  • 1: 1bit画像(二値画像)
  • L: 8bitグレースケール画像
  • RGBA: アルファチャンネルを持った画像

マスク画像が8bitグレースケール(mode='L')の場合、0(黒)ではベース画像が100%、255(白)では貼り付け画像が100%、中間値では2つの画像が値に応じてブレンドされる。

ImageDrawモジュールで黒地に白の円を描画しマスク画像を生成する。

mask_im = Image.new("L", im2.size, 0)
draw = ImageDraw.Draw(mask_im)
draw.ellipse((140, 50, 260, 170), fill=255)
mask_im.save('data/dst/mask_circle.jpg', quality=95)

Pillow Image.paste マスク画像 円

Pillowによる図形描画については以下の記事を参照。

この画像をマスク画像として貼り付け処理を行う。貼り付け画像を円形にマスクできる。

back_im = im1.copy()
back_im.paste(im2, (0, 0), mask_im)
back_im.save('data/dst/rocket_pillow_paste_mask_circle.jpg', quality=95)

Pillow Image.paste 結果画像 円形マスク

マスク画像をImageFilterモジュールを使ってぼかすと、境界をブレンドして貼り付けることができる。

mask_im_blur = mask_im.filter(ImageFilter.GaussianBlur(10))
mask_im_blur.save('data/dst/mask_circle_blur.jpg', quality=95)

back_im = im1.copy()
back_im.paste(im2, (0, 0), mask_im_blur)
back_im.save('data/dst/rocket_pillow_paste_mask_circle_blur.jpg', quality=95)

Pillow Image.paste マスク画像 円 ぼかし Pillow Image.paste 結果画像 円形マスク ぼかし

夜空となめらかに合成されている。

ImageDrawで描画した幾何学的な図形に限らず、マスク画像を準備さえすれば任意の形状で貼り付けられる。

白黒の馬の形の画像(scikit-imageのサンプル: skimage.data.horse())を使ってみる。

Pillow Image.paste マスク画像 馬形

open()で画像を読み込んだあと、resize()で貼り付け画像のサイズに合わせ、convert()でモードを'L'(グレースケール)に変換する。

mask_im = Image.open('data/src/horse.png').resize(im2.size).convert('L')

back_im = im1.copy()
back_im.paste(im2, (100, 50), mask_im)
back_im.save('data/dst/rocket_pillow_paste_mask_horse.jpg', quality=95)

Pillow Image.paste 結果画像 馬形マスク

あまりいい例ではないが複雑な形状で貼り付けられている。星形とかハート形とかの画像を用意すれば色々な場面で使えそう。

マスク画像の白と黒を反転したい場合は以下の記事を参照。

関連カテゴリー

関連記事