⛳
[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