python Pillow(PIL) で画像を生成する
2024/01/18 00:00:00
前提 #
- 開発環境は wsl2 ubuntu20.04
構築手順は以下を参照
https://blog.oya3.net/docs/ubuntu/22.04/ubuntu-settings/ - 本内容で作成したサンプルソース一式
https://github.com/oya3/pyimage
準備 #
python 3.11.7 の開発環境構築
$ mkdir python-image
$ cd python-image
$ pyenv local 3.11.7
$ python -m venv venv
$ source venv/bin/activate
$ pip install pillow
...
[notice] A new release of pip is available: 23.2.1 -> 23.3.2
[notice] To update, run: pip install --upgrade pip
# pip 更新の通知がでれば更新しておく
$ pip install --upgrade pip
# requirements.txt を作成しておく
# 作成済みの場合、 $ pip install -r requirements.txt でパッケージインストール可能
$ pip freeze > requirements.txt
# エディタで静的解析が必要な場合(poetry使わないと開発用パッケージが混ざるので注意)
$ pip install jedi flake8 importmagic autopep8 yapf black
画像生成 #
以下に画像を生成するサンプルを示す
サンプルソースは以下の内容を示している
- サンプルアプリ実行時の入力引数の解析
- フォントサイズからピクセル数に変換
- フォントと線から画像1を作成
- フォントと線から画像2を作成
- 画像1と画像2を結合し新画像を作成
- 新画像から各画像フォーマットファイルを作成
- PNG
- JPEG
- GIF
$ emacs create_image.py
1from PIL import Image, ImageDraw, ImageFont, ImageOps
2import argparse
3import traceback
4
5# フォントサイズは32.0としておく
6FONT_SIZE = 32.0
7# フォントは環境に応じて設定する
8# - windows: MS ゴシック: 'C:/Windows/Fonts/msgothic.ttc'
9# - ubuntu22.04: UbuntuMono: '/usr/share/fonts/truetype/ubuntu/UbuntuMono-RI.ttf'
10FONT_NAME = '/usr/share/fonts/truetype/ubuntu/UbuntuMono-RI.ttf'
11
12def font2PixcelSize(pt):
13 '''
14 フォントptからピクセルに変換
15 '''
16 return ((pt * 96.0) / 72.0)
17
18
19def mm2PixcelSize(mm):
20 '''
21 mm からピクセルに変換
22 '''
23 return ((mm * 96.0) / 27)
24
25
26def create_image(message):
27 width = 200
28 height = int(font2PixcelSize(FONT_SIZE)) # フォントサイズからピクセルの高さを計算
29 image = Image.new('RGB', (width, height), (255, 255, 255)) # width x height のピクセル画像エリアを作成し、背景色は白色にする
30 draw = ImageDraw.Draw(image)
31 # 色は色見本文字列でも指定可能 ex: 'Red': (255, 0, 0)
32 # https://www.colorhexa.com/color-names
33 draw.line((0, 0, width, 0), fill=(255, 0, 0), width=1) # 上部に赤線を引いておく
34 draw.line((0, height-1, width, height-1), fill=(0, 255, 0), width=1) # 下部に緑線を引いておく
35 font = ImageFont.truetype('/usr/share/fonts/truetype/ubuntu/UbuntuMono-RI.ttf', FONT_SIZE)
36 anchor = 'la' # la=左, ma=中央, ra=右
37 draw.text((0, 0), message, (0, 0, 0), spacing=0, align='left', anchor=anchor, font=font) # message 文字列を描画する
38 return image
39
40
41def concat_image(base_image, add_image):
42 # サイズはbase_imageを基準にする
43 new_image = Image.new('RGB', (base_image.width, base_image.height + add_image.height))
44 new_image.paste(base_image, (0, 0)) # base_image を書き込み
45 new_image.paste(add_image, (0, base_image.height)) # add_image を base_image に下部に書き込み
46 return new_image
47
48
49def main(args):
50 image1 = create_image('image1') # 画像1を作成
51 image2 = create_image('image2') # 画像2を作成
52 new_image = concat_image(image1, image2) # 画像1と画像2を結合して新画像を作成
53 new_image.save(args.imagefile+'.PNG') # 新画像からPNG 形式画像ファイルを出力。PNG指定はデフォルト。new_image.save(imagefile+'.PNG', 'PNG') と同じ
54 # 指定可能なフォーマットは PNG, JPEG, PPM, GIF, TIFF, BMP ... JPEG,GIF をサンプル出力しておく
55 new_image.save(args.imagefile+'.JPEG', 'JPEG')
56 new_image.save(args.imagefile+'.GIF', 'GIF')
57
58
59if __name__ == '__main__': # プログラム実行ポイント
60 try:
61 # 入力引数設定
62 parser = argparse.ArgumentParser(description='png画像生成')
63 parser.add_argument('imagefile', help='image ファイル') # 入力引数1:生成した画像を保存するファイル名
64 args = parser.parse_args() # 入力引数取得
65 main(args)
66 except Exception: # main() で発生する異常はすべてキャッチする
67 t = traceback.format_exc()
68 print("ERROR: {}".format(t))
実行
# test.xlsx は入力引数1番で、出力するexcelファイル名を示す
$ python create_image.py image
complete
参考UR #
- Pythonの画像処理ライブラリPillow(PIL)の使い方
https://note.nkmk.me/python-pillow-basic/