このページでは、Pillow (PIL) の text
メソッドで日本語の文字列が描画できない・日本語の文字列を描画すると文字化けする問題の解決方法を紹介していきます。
下記ページでも解説しているように Pillow の text
メソッドを利用すれば画像に文字列を描画することができます。
ですが、日本語の文字列を描画すると下の図のように文字化けすることがあります。オレンジ部分は実は「こんにちは」を描画した結果ですが、跡形もなく文字化けしてますね…。
このページでは、このような描画した日本語の文字列の「文字化けの原因」や「文字化けの解決方法」について説明していきます。
文字化けする問題の解決方法
様々な原因が考えられますが、文字化けする問題の解決方法として一番に挙げられるのが「使用するフォント」の見直しになります。
日本語の文字列が文字化けする原因
「日本語に対応していないフォント」を使用している場合、日本語の文字列を描画しようとすると文字化けが発生します。もしくは、何も描画されないことになります。
日本語非対応のフォントで日本語が正しく描画できないことは当たり前で、この点については理解していただけると思います。
そして、おそらくですが、Mac においても Windows においても Pillow の text
メソッドで文字列を描画する際に利用されるデフォルトのフォントは日本語に非対応です。したがって、フォントの設定をせずに日本語の文字列を描画した場合、基本的に文字化けすると考えて良いです。
そのため、日本語を正しく描画したいのであれば、必ず text
メソッドで文字列を描画する際に利用されるフォントを変更してやる必要があります。
スポンサーリンク
フォントを変更して文字化けを解決
文字化けする原因が「フォントが日本語に対応していないこと」なのであれば、日本語に対応しているフォントに変更してやれば問題は解決します。単純明快ですね!
Mac においては、デフォルトでインストールされている “日本語に対応しているフォント” として下記のようなものが挙げられます。
AquaKana.ttc
ヒラギノ丸ゴ ProN W4.ttc
ヒラギノ明朝 ProN.ttc
ヒラギノ角ゴシック W0.ttc
ヒラギノ角ゴシック W1.ttc
また、Windows においては、デフォルトでインストールされている “日本語に対応しているフォント” として下記のようなものが挙げられます。
HGRGE.TTC
meiryo.ttc
msgothic.ttc
msmincho.ttc
yumin.ttf
したがって、Pillow の text
メソッドが利用するフォントを上記のフォントに変更してやれば文字化けが解決します。
フォントの変更方法
ここまでの説明の内容を踏まえると、結局はフォントを先ほど列挙したものに変更してやることで文字化けが解決することになります。
じゃあ、どうやってフォントを変更すれば良いのか?
この点については下記ページで説明しているので、詳しくは下記ページをご参照いただければと思います。
【Pillow/Python】textメソッドで描画する文字のフォントやサイズを変更するとにかく文字化けを解消したいのであれば、先ほど列挙したフォントのフォントオブジェクトを生成し、text
メソッドの font
引数に生成したフォントオブジェクトを指定してやれば良いだけになります。
フォントオブジェクトは ImageFont
モジュールの truetype
関数で生成することができます。そして、truetype
関数では第1引数(font
引数)に指定したパスのフォントファイルに基づいたフォントオブジェクトが生成されることになります。したがって、truetype
関数の第1引数に、前述で紹介したような “日本語に対応しているフォント” のパスを指定してやれば、日本語に対応したフォントオブジェクトが生成されることになります。あとは、そのフォントオブジェクトを text
メソッドの font
引数に指定してやれば良いだけです。
文字化けを解決したスクリプト
文章だけでみると難しそうに感じるかもしれませんが、実際のスクリプトを見てみれば単純です。
ということで、ここで文字化けを解消したスクリプトの具体的な例を紹介しておきます。利用できるフォントが OS 毎に異なるため、Mac 向けと Windows 向けのスクリプトを紹介します。といっても、両方のスクリプトの違いは font_path
に指定するパスが異なるだけで、他は全く同じものになります。
Mac 向けのスクリプト
Mac 向けの「文字化けを解決するスクリプト」の例は下記のようなものになります。フォントには ヒラギノ丸ゴ ProN W4.ttc
を利用するようにしています。
from PIL import Image, ImageDraw, ImageFont
# 使用するフォント
font_path = 'ヒラギノ丸ゴ ProN W4.ttc'
# 描画する文字列
msg = '文字列の、描画☆'
# Imageオブジェクトの生成
image = Image.new('RGB', (200, 100), 'lightgray')
# Drawオブジェクトの生成
drawer = ImageDraw.Draw(image)
# ヒラギノ丸ゴ ProN W4.ttcで描画
font = ImageFont.truetype(font=font_path, size=20)
drawer.text(xy=(100, 50), text=msg, fill='black', anchor='mm', font=font)
# 文字列描画後の画像を表示
image.show()
ポイントは、truetype
関数の実行によってフォントオブジェクト font
を生成している個所になります。truetype
関数の第1引数に日本語に対応しているフォントのパスである 'ヒラギノ丸ゴ ProN W4.ttc'
を指定しているため、日本語に対応したフォントオブジェクトが生成されることになります。
それを text
メソッドの font
引数に指定しているため、text
メソッドでは日本語の描画を行うことが可能となります。
実際にスクリプトを実行して表示される画像は下図のようなものになり、日本語の文字列が文字化けすることなく描画されていることが確認できると思います。
また、上記のスクリプトにおける text
メソッドの各種引数については下記ページで解説していますので、引数の意味合いが気になる方は下記ページをご参照いただければと思います。
Windows 向けのスクリプト
Windows 向けの「文字化けを解決するスクリプト」の例は下記のようなものになります。フォントには meiryo.ttc
(メイリオ) を利用するようにしています。
from PIL import Image, ImageDraw, ImageFont
# 使用するフォント
font_path = 'meiryo.ttc'
# 描画する文字列
msg = '文字列の、描画☆'
# Imageオブジェクトの生成
image = Image.new('RGB', (200, 100), 'lightgray')
# Drawオブジェクトの生成
drawer = ImageDraw.Draw(image)
# meiryo.ttcで描画
font = ImageFont.truetype(font=font_path, size=20)
drawer.text(xy=(100, 50), text=msg, fill='black', anchor='mm', font=font)
# 文字列描画後の画像を表示
image.show()
スクリプトを実行して表示される画像は下図のようなものになり、日本語の文字列が文字化けすることなく描画されていることが確認できると思います。
以上が、文字列描画時に日本語文字列が文字化けしてしまうことの原因および、その解決方法になります。
スポンサーリンク
日本語に対応しているフォントの調べ方
ここからはオマケです。
ここまで説明してきた方法で文字化けを解消するためには「日本語に対応しているフォント」を調べておく必要があります。先ほど日本語に対応しているフォントの例を紹介しましたが、これは一例であり全てを列挙したわけではありません。
では、自身の PC にインストールされている全てのフォントに対して日本語への対応の有無を調べるにはどうすれば良いでしょうか?
正直、良い方法ではないのですが、インストールされている各々のフォントを利用して日本語文字列の描画をトライし、描画後の画像で文字列が文字化けしているかどうかを確認してみれば、各フォントの日本語への対応の有無を調べることは可能です。文字化けしなければ日本語に対応していると考えられます。
例えば下記のスクリプトを実行すれば、フォントのインストールフォルダ内のフォントファイル全てを探索し、それらのフォントファイルを利用して日本語の文字列の描画が行われることになります。描画結果は japanese
フォルダに フォントファイル名.png
の名前で保存されますので、保存された画像を確認すれば、各フォントの日本語対応の有無を確認することができます。
from PIL import Image, ImageDraw, ImageFont
import os
save_dir = 'japanese'
# for MacOSX
font_dirs = [
'/Library/Fonts',
'/System/Library/Fonts',
os.path.expanduser('~/Library/Fonts'),
]
# for Windows
# font_dirs = [os.environ.get('WINDIR') + '\\Fonts']
if not os.path.isdir(save_dir):
os.mkdir(save_dir)
font_paths = []
for font_dir in font_dirs:
for root_path, dir_paths, files in os.walk(top=font_dir):
for font_path in files:
font_paths.append(font_path)
for font_path in font_paths:
# 描画する文字列
msg = '文字列の、描画☆'
# Imageオブジェクトの生成
image = Image.new('RGB', (200, 100), 'lightgray')
# Drawオブジェクトの生成
drawer = ImageDraw.Draw(image)
# 文字列を描画してみる
try:
drawer.font = ImageFont.truetype(font=font_path, size=20)
except Exception as e:
# フォントオブジェクトが生成できなかった場合
print(font_path, e)
continue
drawer.text(xy=(100, 50), text=msg, anchor='mm', fill='black')
# 文字列描画後の画像を表示
image.save(save_dir + '/' + font_path + '.png')
このスクリプトは Mac 向けのフォントフォルダの中を検索するものになっていますが、下記のコメントアウトを外せば Windows 向けのスクリプトとなります。
# font_dirs = [os.environ.get('WINDIR') + '\\Fonts']
前述のとおり、実行すると下の図のように japanese
フォルダに日本語で文字列を描画した結果の画像が保存されます。1つ1つ確認していけば、どのフォントが日本語文字列の描画に対応しているのかを調べることが出来ると思います!まぁ、1つ1つ画像を確認するのが面倒ですが…。もっといい方法が思いつけば追記して紹介したいと思います!
まとめ
このページでは、Pillow (PIL) の text
メソッドで日本語の文字列が描画できない・日本語の文字列を描画すると文字化けする問題の解決方法を紹介しました!
こういった現象が発生する原因として最初に疑うべきはフォントです。text
メソッドから文字列を描画時に利用されるフォントが日本語に対応していないと日本語の文字列描画時に文字化けが発生します。もしくは、何も描画されないことになります。
そして、Pillow の text
メソッドでデフォルトで利用されるフォントは日本語に対応していません。そのため、フォントを変更せずにデフォルト設定のまま text
メソッドで日本語文字列を描画すると、ほぼ間違いなく上記の現象が発生すると思います。
原因がフォントにあるのであれば日本語に対応しているフォントを利用するようにしてやれば上記の現象は解決することが出来ます。OS によって使用できるフォントが異なるので注意が必要ですが、日本語に対応しているフォントの例や日本語に対応しているフォントの調べ方についても本ページで説明していますので、これらを参考に text
メソッドから利用されるフォントを日本語に対応しているものに変更して再度日本語文字列の描画にトライしてみてください!
また、text
メソッドから利用されるフォントの設定方法については下記ページで詳しく説明していますので、フォントの設定方法について学びたい方はぜひ下記ページも読んでみてください!