⛳
[Python] OGPっぽい画像を作る
はじめに
% cogp OGPっぽい画像を作りたい ogp
とすると、下のような画像がzennのimages配下にogp.pngとして保存するコマンドを作成する

こういうやつを作りたい
動作環境
| バージョン | |
|---|---|
| macOS | macOS14.4 (23E214) |
| Python | 3.12.3 |
概要
引数
| 引数 | 概要 |
|---|---|
| 第1引数 | 画像内の文字 |
| 第2引数 | 出力画像ファイル名 |
特徴
% cogp test1\\ntest2 test

- 入力文字列内に
\\nを含めると、そこで改行される - 右下に作成日を付ける
手順
- figmaで背景の土台を作る
- Pythonでコードを書く
- 実行権限を付与し、パスを通す
figmaで土台を作る
地味に頑張る

OGP_foundation.png
ディレクトリ構成
% tree -L 2
.
├── OGP_foundation.png
├── README
├── cogp
├── cogp_venv
│ ├── bin
│ ├── include
│ ├── lib
│ └── pyvenv.cfg
└── irohakakuC-Medium.ttf
Pythonでコードを書く
全体コード
使用ライブラリ
-
PIL: 画像生成 -
datetime: 日時を取得 -
sys: コマンドで引数を取得 -
os: パスを作成
コード概要
大雑把に説明しています。
gist↑を参照しながら見たほうがいいです。
- シバン(shibang)
スクリプトファイルの先頭に書く行で、スクリプトを実行する処理系(インタプリタ)を指定する仕組み
マシンに、「Pythonのコードですよ〜」っていうのを明示的に示している
#! /usr/bin/env python3
-
ファイルが保存されている絶対パスを取得する
土台画像のOGP.pngと、フォントのパスを取得するために必要
(相対パスではなく、絶対パスで欲しいため)
parent_dir=os.path.dirname(os.path.abspath(__file__))
- wrap_text関数で改行処理を行う
引数
-
text: 入力文字 -
max_width: 1行の文字の長さの上限 -
font: 使用フォントを指定
- 入力文字を
\nで分割する
test_line = f"{current_line}{char}"
- 分割された文字列に対して以下の処理を行う
処理
- 仮に
current_lineに次の一文字を追加してみて、テキストの長さを取得する
test_line = f"{current_line}{char}"
width, height = draw.textbbox(
(0, 0, image_width, image_height), test_line, font=font
)[2:]
- テキストの長さが
max_widthを超えなければそれを新たにcurrent_lineとする
if width <= max_width:
current_line = test_line
- 超えてしまった場合、1文字追加前のテキストを
lines配列に格納
if current_line:
lines.append(current_line)
-
current_lineを、追加する1文字で初期化する(改行)
current_line=char
-
forを抜けた後に、
current_lineをlines配列に格納する -
入力文字の高さを調べ、全体の高さを調べる
if lines:
line_bbox = draw.textbbox(
(0, 0, image_width, image_height), lines[0], font=font
)
line_height = line_bbox[3] - line_bbox[1]
else:
line_height = 0
# 全部の行の高さ
total_text_height = line_height * len(lines)
start_y = (image_height - total_text_height) // 2
- 画像の中心に文字を描画
- 名前と日付を描画する
シェルではバックスラッシュがエスケープされてしまうので、\\nと入力する
コード内で\\n→\nと置換する
title = sys.argv[1].replace("\\n", "\n")
おわりに
これから使っていこ〜
Discussion