OGP 画像のタイトルを作成する 実装方針の比較と検討
- Python
概要
- この自作ブログの OGP 画像は Python と GitHub Actions を使って自動生成するようになっています。ブログのタイトルを使用して良い感じに調整することで、OGP 画像のタイトルをつけます。しかし、先日投稿したブログの OGP 画像のタイトルのレイアウトが崩れていました。そこで、今回は OGP 画像のタイトルをつけるための実装方針を再度考え直します。そして、実装に必要なライブラリの比較と検討を行いたいと思います。
事の発端 (原因) とライブラリの比較と検討を行おうと思った背景
- 先日投稿したブログエントリの CyberAgent のコンテナ技術に関する勉強会に参加してきた の OGP 画像が意図した形になっていませんでした。以下の図 1 の画像が実際に生成されていた OPG 画像で、図 2 のような画像が生成されて欲しかった画像です。
図 2 では、日本語の文脈的にもレイアウト的にも良い感じの箇所で改行されています。一方、図 1 では、タイトルの 2 行目が長くなりすぎてしまい、端の文字が切れてしまっています。そこでまず、現時点での OGP 画像を生成するためのロジックについて説明したいと思います。
まず、タイトルがそれほど長くない場合 (30 文字以内) には、そのままタイトルを付けるようにしています。しかし、タイトルが 30 文字より大きくなると、改行処理を挟んでタイトルを付けるような実装になっています。この改行処理には、textwrap という Python の標準ライブラリを活用しています。つまり、タイトルが 30 文字以上の場合には、textwrap のアルゴリズムに従ってタイトルの分割処理が行われます。その分割処理によって、改行させてタイトルを付けます。
これに加えて、Hugo のフロントマターに追加するフラグに応じた改行処理も実装されています。Hugo のフロントマターのタイトルの箇所に改行用のフラグ (
\n
) を追加すると、それを起点に改行された OGP 画像が生成されます。つまり、手動でタイトルの改行箇所を決めることができます。まとめると、textwrap と Hugo のフロントマターに改行用のフラグ (
\n
) を追加する 2 つの方式のハイブリッドで OGP のタイトルを付けるような実装になっていました。しかし、この前者の実装では、
width=30
を指定して、textwrap.wrap() を呼び出しています。このwidth
のパラメータは、与えられた引数の文字列の各行がwidth
以下になるように wrap されます。タイトルがwidth
以下だと特に問題は生じません。しかし、適用するタイトルによっては、変な箇所で改行処理が行われることが明らかになりました。例えば、CyberAgent のコンテナ技術に関する勉強会に参加してきた
は、CyberAgent
とのコンテナ技術に関する勉強会に参加してきた
に分割されます。自分は標準ライブラリの内部の実装をそれほど考慮せず OGP 画像のタイトルを付けるためのロジックを実装していました。そのため、てっきりCyberAgent のコンテナ技術に関する勉強会に参加して
ときた
に分割されるものと思っていました。これは、前半部分が 30 文字で後半部分が 2 文字だからです。たとえそうだったとしても、意図した挙動ではなかったのですが …そこで、これらを踏まえて、再度 OGP 画像のタイトルを付けるためのロジックやライブラリを再度調査することにしました。そして、調査した実装方針を比較検討することにしました。
実装の方針の洗い出し
OGP 画像にタイトルを付けるために洗い出した実装方法を以下にまとめました。現時点での実装は、自動で行う方法の 1 と手動で行う方法の 1 のハイブリッドな実装となっています。
自動で行う方法
- textwrap を活用して雑に改行させる
- textwrap を拡張して好みの形で改行させる
- google/budoux を活用してタイトルを日本語として意味のある形に分割して改行させる
手動で行う方法
- Hugo のフロントマターのタイトルに改行させたい箇所に
\n
を差し込み、Python の OGP 画像を作成するスクリプトで改行させる
- Hugo のフロントマターのタイトルに改行させたい箇所に
自動で行う方法の 3 の google/budoux というライブラリは、Twitter で知りました。これは、機械学習を活用した文章を意味のある単位に分割するライブラリです。README.md にも書かれているように、例えば
あなたに寄り添う最先端のテクノロジー。
という文字列をこのライブラリを用いて分割するとします。その結果、あなたに
と寄り添う
と最先端の
とテクノロジー。
に分割されます。こうして日本語の文章を意味のある単位に分割することが確認できます。この結果から、google/budoux はこのブログの OGP 画像の生成に応用できるのではないかと思い、以前から試したいと思っていました。
実装の方針の比較
ここでは、前章で述べた各実装方針のメリットとデメリットについて考えたいと思います。
自動で行う方法の 1
- よくよく考えると、必要ありません。2 行以上になると日本語の文脈的に意味のある箇所で改行させる必要があります。そのため、
textwrap.wrap()
のデフォルトのアルゴリズムでは今回のように上手くいかないケースがどうしても出てきてしまうためです。
- よくよく考えると、必要ありません。2 行以上になると日本語の文脈的に意味のある箇所で改行させる必要があります。そのため、
自動で行う方法の 2
- デフォルトのアルゴリズムを書き換えたり拡張しても、意味のある箇所で改行させるには、結局自然言語処理が必要となってきます。そのため、そういったロジックを自前で実装することは難しいと判断しました。
自動で行う方法の 3
- google/budoux を活用すると、ブログのタイトルを意味のある単位で分割することができます。しかし、分割させた単位でどう結合させた上で改行させるかには好みが出てしまいます。そのため、このライブラリを活用したとしても OGP 画像の生成の自動化は難しいと思いました。
手動で行う方法の 1
- Hugo のフロントマターに改行させたい箇所に
\n
を追加し、それに応じて OGP 画像のタイトルの改行処理を行います。この方法は、手動で行うため、タイトルが長い場合には、改行フラグを追加するのを忘れないようにしないといけません。しかし、自分好みの箇所で OGP 画像にタイトルを付けられるメリットがあります。また、このタイトルを手動で付けるロジックはすでに実装済みです。したがって、タイトルがどうしても長くなる場合には、\n
を差し込むのを忘れないようにして、運用でカバーするようにします。
- Hugo のフロントマターに改行させたい箇所に
実装の方針の比較と検討 (結論)
- タイトルが長くなる場合には、手動で
\n
を追加し、日本語として違和感の感じない箇所に改行フラグを追加することで、OGP 画像のタイトルを生成するような実装に落ち着きました。つまり、実装はそのままで、運用でカバーするようにします。
最後に
- OGP 画像のタイトルを作成するライブラリの比較と検討に当たって textwrap や google/budoux の実装をソースコードレベルで追ったりしました。その調査は大変面白かったので、その内容に関しては、別の記事でまとめたいと思います🤞