pillowを使って図形を描画する機会があったのだが、デフォルトのまま描画するとバキバキの画像になってしまった。きれいにしたければ倍の大きさで書き出し、リサイズするときにアンチエイリアスを指定すればいいらしいが、ちょっとめんどくさい。
最初からきれいに描けるモジュールを見つけたので書いておく。
参考 https://stackoverrun.com/ja/q/3880127
参考 https://aggdraw.readthedocs.io/en/latest/
#pillowで普通に描く
pollowをつかって普通に描くとこんな感じ。角の処理もされず、ジャギも出ているのがわかるだろうか。
from PIL import Image, ImageDraw
image = Image.new('RGB', (300, 300), (255, 255, 255))
draw = ImageDraw.Draw(image)
draw.line((150, 50, 250, 250, 50, 250, 150, 50), fill=(0, 0, 0), width=20)
draw.line((10, 140, 290, 160), fill=(0, 0, 0), width=20)
image.save('test1.png', quality=100)
#pillowで普通に描いて角を丸める
一応、角の丸めに関してはバージョンの新しめのpillowなら実装されている。
joint="curve" を引数に追加してやればいい。
from PIL import Image, ImageDraw
image = Image.new('RGB', (300, 300), (255, 255, 255))
draw = ImageDraw.Draw(image)
draw.line((150, 50, 250, 250, 50, 250, 150, 50), fill=(0, 0, 0), width=20, joint="curve")
draw.line((10, 140, 290, 160), fill=(0, 0, 0), width=20)
image.save('test2.png', quality=100)
これで角は丸められる。書き始めと書き終わりの部分が処理されないので、気になるなら最初の一辺をもう一度なぞるといい。
from PIL import Image, ImageDraw
image = Image.new('RGB', (300, 300), (255, 255, 255))
draw = ImageDraw.Draw(image)
draw.line((150, 50, 250, 250, 50, 250, 150, 50, 250, 250), fill=(0, 0, 0), width=20, joint="curve")
draw.line((10, 140, 290, 160), fill=(0, 0, 0), width=20)
image.save('test3.png', quality=100)
#aggdrawで描く
インストールは普通にpipでいけた
pip install aggdraw
aggdrawでは、pillowで作ったImageにそのまま描画できる。penを定義して、それで書いていく感じ。アンチエイリアスやアルファ合成も勝手にやってくれるので、ジャギが消えているのがわかるだろうか?
from PIL import Image
import aggdraw
image = Image.new('RGB', (300, 300), (255, 255, 255))
draw = aggdraw.Draw(image)
pen = aggdraw.Pen((0, 0, 0), 20)
draw.line((150, 50, 250, 250, 50, 250, 150, 50, 250, 250), pen)
draw.line((10, 140, 290, 160), pen)
draw.flush()
image.save('test4.png', quality=100)
#おまけ
ブラシ(塗りつぶし)もあるよ
from PIL import Image
import aggdraw
image = Image.new('RGBA', (300, 300), (255, 255, 255, 255))
draw = aggdraw.Draw(image)
brush = aggdraw.Brush((0, 0, 0), 255)
draw.line((150, 50, 250, 250, 50, 250, 150, 50, 250, 250), brush)
draw.flush()
image.save('test5.png', quality=100)