Python, Pillowで円や四角、直線などの図形を描画
Pythonの画像処理ライブラリPillow(PIL)のImageDraw
モジュールに、円や四角、直線などの図形を描画するメソッドが多数用意されている。
ここでは以下の内容について説明する。
- Pillow(PIL)の
ImageDraw
で図形を描画する流れDraw
オブジェクト生成- 図形描画メソッドで図形を描画
- 図形描画メソッドの共通の引数
- 座標:
xy
- 塗りつぶし色:
fill
- 枠線の色:
outline
- 座標:
- 図形描画メソッドの例
- 楕円、四角
- 直線、多角形、点
- 円弧、弦、パイ
- 読み込んだ画像の上に描画
Pillow(PIL)の基本的な使い方および文字の描画については以下の記事参照。
OpenCVでの図形描画は以下の記事参照。
Pillow(PIL)のImageDrawで図形を描画する流れ
Drawオブジェクト生成
背景となる画像(図形を描画する画像)のImage
オブジェクトを準備し、それを使ってDraw
オブジェクトを生成する。Image
とImageDraw
をインポートするのを忘れずに。
from PIL import Image, ImageDraw
im = Image.new('RGB', (500, 300), (128, 128, 128))
draw = ImageDraw.Draw(im)
ここではImage.new()
でベタ画像を作成。モード、サイズ、塗りつぶす色を引数で指定している。
図形描画メソッドで図形を描画
Draw
オブジェクトの図形描画メソッドを呼び出して、図形を描画する。
例として楕円、四角、直線を描画する。引数については後述。
draw.ellipse((100, 100, 150, 200), fill=(255, 0, 0), outline=(0, 0, 0))
draw.rectangle((200, 100, 300, 200), fill=(0, 192, 192), outline=(255, 255, 255))
draw.line((350, 200, 450, 100), fill=(255, 255, 0), width=10)
im.save('data/dst/pillow_imagedraw.jpg', quality=95)
図形描画メソッドの共通の引数
メソッドによって違いはあるが、以下の引数が共通している。
座標: xy
図形を描画する矩形領域などの座標を設定する。
以下のいずれかの形式で指定する。
((左上のx座標, 左上のy座標), (右下のx座標, 右下のy座標))
(左上のx座標, 左上のy座標, 右下のx座標, 右下のy座標)
line()
やpolygon()
、point()
では矩形領域を表す2点ではなく、複数の座標を指定する。
(x1, y1, x2, y2, x3, y3...)
((x1, y1), (x2, y2), (x3, y3)...)
line()
では各点を結んだ直線(折れ線)、polygon()
では各点と最初と最後の点が結ばれた多角形、point()
では各点に1ピクセルの点が描画される。
塗りつぶし色: fill
図形を塗りつぶす色を設定する。
指定形式は画像(Image
オブジェクト)のモードによって異なる。
RGB
: それぞれの色の階調(0〜255)を(R, G, B)
で指定L
(グレースケール) : 0〜255の整数値で指定
デフォルトはNone
(塗りつぶしなし)。
枠線の色: outline
図形の枠線の色を設定する。
色の指定形式は上のfill
と同じ。こちらもデフォルトはNone
(枠線なし)。
残念ながら、バージョン4.4.0
時点では、line()
メソッド以外には線幅(線の太さ)を設定するオプションはない。
図形描画メソッドの例
詳細は公式ドキュメント参照。
楕円、四角
- 楕円(円):
ellipse(xy, fill, outline)
- 四角(長方形、正方形) :
rectangle(xy, fill, outline)
ellipse()
は引数xy
で指定する矩形領域に接する楕円が描画される。正方形を指定すると正円になる。
出力結果は上の例で示した通り。
直線、多角形、点
- 直線 :
line(xy, fill, width)
xy
((x1, y1), (x2, y2), (x3, y3)...)
のように2点以上の複数の座標を指定する。- 各点を結んだ直線が描画される。
width
: 線幅(線の太さ)width
で線幅を太くした場合、xy
で3点以上指定すると接続部が不格好になる。
- 多角形 :
polygon(xy, fill, outline)
xy
((x1, y1), (x2, y2), (x3, y3)...)
のように3点以上の複数の座標を指定する。- 各点と最初と最後の点が結ばれた多角形が描画される。
- 点 :
point(xy, fill)
xy
((x1, y1), (x2, y2), (x3, y3)...)
のように1点以上の複数の座標を指定する。- 各点に1ピクセルの点が描画される。
直線(line()
)、多角形(polygon()
)、点(point()
)の例。点は1ピクセルなので見づらいが右側に描画されている。
im = Image.new('RGB', (500, 250), (128, 128, 128))
draw = ImageDraw.Draw(im)
draw.line(((30, 200), (130, 100), (80, 50)), fill=(255, 255, 0))
draw.line(((80, 200), (180, 100), (130, 50)), fill=(255, 255, 0), width=10)
draw.polygon(((200, 200), (300, 100), (250, 50)), fill=(255, 255, 0), outline=(0, 0, 0))
draw.point(((350, 200), (450, 100), (400, 50)), fill=(255, 255, 0))
円弧、弦、パイ
引数xy
で指定する矩形領域に接する円弧、弦(弓)、パイが描画される。
- 円弧 :
arc(xy, start, end, fill)
start
,end
- 弧の角度をdegree(度)で指定する。
- 0度は3時の方向。時計回り。
- 弦(弓) :
chord(xy, start, end, fill, outline)
- 円弧の開始点と終了点が直線で結ばれる。
- パイ :
pieslice(xy, start, end, fill, outline)
- 円弧の開始点と終了点と中心が直線で結ばれる。
円弧(arc()
)、弦(chord()
)、パイ(pieslice()
)の例。
im = Image.new('RGB', (600, 250), (128, 128, 128))
draw = ImageDraw.Draw(im)
draw.arc((25, 50, 175, 200), start=30, end=270, fill=(255, 255, 0))
draw.chord((225, 50, 375, 200), start=30, end=270, fill=(255, 255, 0), outline=(0, 0, 0))
draw.pieslice((425, 50, 575, 200), start=30, end=270, fill=(255, 255, 0), outline=(0, 0, 0))
読み込んだ画像の上に描画
これまでの例ではImage.new()
で生成したベタ画像の上に図形を描画しているが、既存の画像ファイルをImage.open()
で読み込めばその上に重畳して描画することもできる。
im = Image.open('data/src/lena.jpg')
draw = ImageDraw.Draw(im)
draw.pieslice((15, 50, 140, 175), start=30, end=330, fill=(255, 255, 0))