note.nkmk.me

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

Date: 2017-11-29 / tags: Python, Pillow, 画像処理
スポンサーリンク

Image.paste()を使う

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

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

コード例

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 マスク画像 円

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

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 結果画像 馬形マスク

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

スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事