Python, Pillowで画像に別の画像を貼り付けるpaste
Pythonの画像処理ライブラリPillow(PIL)のImage
モジュールに、画像を貼り付けるメソッドpaste()
が用意されている。
Pillow(PIL)のインストール、基本的な使い方などは以下の記事参照。
ここでは、paste()
を使った画像の貼り付けについて以下の三通りを説明する。
- 通常の貼り付け
- 貼り付ける位置を指定
- マスク画像を使用
PIL
からImage
をインポートして、ベース(背景)となる画像と貼り付ける画像をそれぞれ開いておく。
ImageDraw
とImageFilter
は最後に説明するマスク画像を設定する際に使用する。単純に貼り付けるだけなら省略して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)
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)
貼り付け画像がベース画像の領域外にはみ出す場合、はみ出した部分は無視される。
back_im = im1.copy()
back_im.paste(im2, (400, 100))
back_im.save('data/dst/rocket_pillow_paste_out.jpg', quality=95)
マスク画像を使用
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による図形描画については以下の記事を参照。
この画像をマスク画像として貼り付け処理を行う。貼り付け画像を円形にマスクできる。
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)
マスク画像を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)
夜空となめらかに合成されている。
ImageDraw
で描画した幾何学的な図形に限らず、マスク画像を準備さえすれば任意の形状で貼り付けられる。
白黒の馬の形の画像(scikit-imageのサンプル: skimage.data.horse())を使ってみる。
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)
あまりいい例ではないが複雑な形状で貼り付けられている。星形とかハート形とかの画像を用意すれば色々な場面で使えそう。
マスク画像の白と黒を反転したい場合は以下の記事を参照。