Python, Pillowで円や四角、直線などの図形を描画

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

Pythonの画像処理ライブラリPillow(PIL)のImageDrawモジュールに、円や四角、直線などの図形を描画するメソッドが多数用意されている。

ここでは以下の内容について説明する。

  • Pillow(PIL)のImageDrawで図形を描画する流れ
    • Drawオブジェクト生成
    • 図形描画メソッドで図形を描画
  • 図形描画メソッドの共通の引数
    • 座標: xy
    • 塗りつぶし色: fill
    • 枠線の色: outline
  • 図形描画メソッドの例
    • 楕円、四角
    • 直線、多角形、点
    • 円弧、弦、パイ
  • 読み込んだ画像の上に描画

Pillow(PIL)の基本的な使い方および文字の描画については以下の記事参照。

OpenCVでの図形描画は以下の記事参照。

Pillow(PIL)のImageDrawで図形を描画する流れ

Drawオブジェクト生成

背景となる画像(図形を描画する画像)のImageオブジェクトを準備し、それを使ってDrawオブジェクトを生成する。ImageImageDrawをインポートするのを忘れずに。

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)

Pillow ImageDraw

図形描画メソッドの共通の引数

メソッドによって違いはあるが、以下の引数が共通している。

座標: 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))

Pillow ImageDraw

円弧、弦、パイ

引数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))

Pillow ImageDraw

読み込んだ画像の上に描画

これまでの例では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))

Pillow ImageDraw

関連カテゴリー

関連記事