PythonのPillowでOpenTypeフォントの拡張書体を使うためのセットアップ
OpenType機能拡張を使ってテキストを描画したい!
PythonのPillowでフォントを指定して文字列を描画する時に、OpenTypeの機能拡張(CSSで言うところのfont-feature-settings。ligaとかpaltのやつ)を有効にする方法…… と言うか、方法自体はtext
メソッドにfeatures引数を追加するだけで簡単なのですが、その状態でエラーなく実行できるようにする方法です。
features引数を使った描画を行うには、libraqmなるライブラリが必要なのですが、使えるようにするために色々インストールしなきゃいけない感じだったので、将来の自分のためにメモしておきます。
って言うか、下記ページに丁寧に解説があるのですが、libraqmのバージョンが新しくなってるっぽくて最後のビルドコマンドだけちょっと違いました。とにかくありがたいことです🙇♂️
Pillow(PIL)でOpenTypeフィーチャーを設定する方法 | hgrs's Blog
https://blog.hgrs.me/20190517125044
あとはダウンロードしたlibraqmライブラリの中にあるREADME.md
にインストール方法が書いてあるので、それ読むのが一番確実。英語だけど……
セットアップ手順
1. Homebrew
先にlibraqmライブラリが使うライブラリ、要するに依存ライブラリをインストールしなきゃいけなくて、そのインストールにはHomebrewを使います。
自分は新しい環境にまだインストールしてなかったのでこの機会にインストール。公式ページの
〈インストール〉のところにある謎の呪文をターミナルにコピペして実行します。この黒い画面使えんば人にあらずみたいな感じ、今でこそ慣れたけど初めてHomebrewインストールする時はおっかなびっくりだったょ……
macOS(またはLinux)用パッケージマネージャー — Homebrew
https://brew.sh/index_ja
2. libraqmが使うライブラリのインストール
$ brew install freetype harfbuzz fribidi gtk-doc
4つのライブラリをまとめてインストールしてる…… のかな?
freetypeと言うのがフォントンレンダリングエンジンで、harfbuzzは「文字列を受け取ってレイアウトに必要な情報を提供する……」とあります。fribidiはbidi(バイディレクショナル)とあるようにアラビア語なんかのレイアウト対応っぽいです。gtk-docはドキュメントジェネレータみたい。
まあよくわかなんないけど上記コマンドコピペしてターミナルで実行するだけなのでヨシ!
3. Meson(とninja)のインストール
$ pip install meson ninja
libraqmに同梱のREADME.md
によると、あとはlibraqm自体をビルドして終わりになっているのですが、同ファイルに記載のビルドコマンドを実行してもそんなコマンド無いの一点張り。というわけで、自分の環境ではそのビルドに使うMesonとNinjaなるものをインストールしないとでした。どちらもビルドシステムみたい。
いずれもPythonのパッケージマネージャであるpipを使ってインストールできます。HomebrewのPython限定版がpipみたいな認識でいいのかな。いずれにしろ、ここに来る時点でpipはインストール済みのハズ(そもそもPillowをpipでインストールしたと思うので)。
4. libraqmのビルド
Mesonが使えるようになったらあとはlibraqmをビルドしてインストールで終わりです。
なおlibraqmのダウンロードはGitHubのlibraqmのページのReleasesから。2022/07/27時点での最新版は0.9.0でした。
ダウンロードしたtar.xzを解凍したraqm-0.9.0
に移動し、下記コマンドを実行してビルドします。
ドキュメントには「in the source code directory:」とあったので、最初はraqm-0.9.0/
で実行したんですが違いました。尤《もっと》も、誤ったディレクトリで実行すると「プロジェクトのルートディレクトリで実行しようとしたんじゃなくて?」と教えてくれるので安心です。
$ meson build
引き続き下記コマンドでさらにビルド、インストールします。なぜ似たようなコマンドが2回必要なのかはよくわかりませんが、最初のコマンドでは 〈Linking Target〉と出て、2回目のinstallで実際にシステムにインストールされてるみたいです。
$ ninja -C build
$ ninja -C build install
お疲れさまでした!
これでPillowでOpenType拡張機能を使ったフォント描画ができるようになるわけです!!
描画メソッドの書き方
簡単です、ImageDraw.text
メソッドにfeatures
引数を追加するだけ。値は'ss01'とか'pwid'とか拡張機能の文字列のリストでOK。なお先頭にマイナスを付けた'-ss01'などを渡すことでその機能をオフにできるようです。
font = ImageFont.truetype('/Users/Sentinel/Library/Fonts/', FONT_SIZE)
drawer = ImageDraw.Draw(pilImage)
drawer.text((textX, textY), '機械彫刻用標準書体', fill=(0, 0, 0), anchor='ls', font=imageFont, features=['ss01'])
以上でーす。
ちなみに、このPillowでのOpenTypeフィーチャーを使った描画は、軸の秤の開発で作った
〈フォント→ビットマップ変換スクリプト〉で必要になりました。実装中のフォースカーブを感熱プリンタに印刷する機能で、日本語フォントとして機械彫刻用標準書体フォントを使いたかったんですが、このフォントはOpenTypeのスタイルセット機能を使って簡易字体が再現できるようになっています。
特に ss01 に割り当てられている
“附属書2の簡易字体”は
「機械彫刻フォント使うならこれしか勝たん」ってぐらい看板感が出てる素晴らしい略しっぷりなので、どうしても拡張機能を使ったフォント描画がしたかったわけです。
この記事はここで終わりです。
読んでいただきありがとうございました。
良かったらシェアしてね!
That's all for this article. Thank you for your reading.
Please share this if you like it!