【Pillow/Python】textメソッドで描画した文字列が文字化けする問題の解決方法

Pillowのtextメソッドで描画した日本語文字列の文字化けの解消方法

このページにはプロモーションが含まれています

このページでは、Pillow (PIL) の text メソッドで日本語の文字列が描画できない・日本語の文字列を描画すると文字化けする問題の解決方法を紹介していきます。

下記ページでも解説しているように Pillow の text メソッドを利用すれば画像に文字列を描画することができます。

PIllowでの画像への文字列の描画の仕方の解説ページアイキャッチ 【Python/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の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 を利用するようにしています。

Mac 向けのスクリプト
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 メソッドでは日本語の描画を行うことが可能となります。

実際にスクリプトを実行して表示される画像は下図のようなものになり、日本語の文字列が文字化けすることなく描画されていることが確認できると思います。

'ヒラギノ丸ゴ ProN W4.ttc'のフォントで文字列を描画した結果

また、上記のスクリプトにおける text メソッドの各種引数については下記ページで解説していますので、引数の意味合いが気になる方は下記ページをご参照いただければと思います。

PIllowでの画像への文字列の描画の仕方の解説ページアイキャッチ 【Python/Pillow】画像に文字列を描画する(textメソッド)

Windows 向けのスクリプト

Windows 向けの「文字化けを解決するスクリプト」の例は下記のようなものになります。フォントには meiryo.ttc (メイリオ) を利用するようにしています。

windows向けのスクリプト
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()

スクリプトを実行して表示される画像は下図のようなものになり、日本語の文字列が文字化けすることなく描画されていることが確認できると思います。

'meiryo.ttc'のフォントで文字列を描画した結果

以上が、文字列描画時に日本語文字列が文字化けしてしまうことの原因および、その解決方法になります。

スポンサーリンク

日本語に対応しているフォントの調べ方

ここからはオマケです。

ここまで説明してきた方法で文字化けを解消するためには「日本語に対応しているフォント」を調べておく必要があります。先ほど日本語に対応しているフォントの例を紹介しましたが、これは一例であり全てを列挙したわけではありません。

では、自身の 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 向けのスクリプトとなります。

WIndows向けのフォントフォルダの設定
# font_dirs = [os.environ.get('WINDIR') + '\\Fonts']

前述のとおり、実行すると下の図のように japanese フォルダに日本語で文字列を描画した結果の画像が保存されます。1つ1つ確認していけば、どのフォントが日本語文字列の描画に対応しているのかを調べることが出来ると思います!まぁ、1つ1つ画像を確認するのが面倒ですが…。もっといい方法が思いつけば追記して紹介したいと思います!

日本語文字列の描画結果が画像ファイルとして保存されていく様子

まとめ

このページでは、Pillow (PIL) の text メソッドで日本語の文字列が描画できない・日本語の文字列を描画すると文字化けする問題の解決方法を紹介しました!

こういった現象が発生する原因として最初に疑うべきはフォントです。text メソッドから文字列を描画時に利用されるフォントが日本語に対応していないと日本語の文字列描画時に文字化けが発生します。もしくは、何も描画されないことになります。

そして、Pillow の text メソッドでデフォルトで利用されるフォントは日本語に対応していません。そのため、フォントを変更せずにデフォルト設定のまま text メソッドで日本語文字列を描画すると、ほぼ間違いなく上記の現象が発生すると思います。

原因がフォントにあるのであれば日本語に対応しているフォントを利用するようにしてやれば上記の現象は解決することが出来ます。OS によって使用できるフォントが異なるので注意が必要ですが、日本語に対応しているフォントの例や日本語に対応しているフォントの調べ方についても本ページで説明していますので、これらを参考に text メソッドから利用されるフォントを日本語に対応しているものに変更して再度日本語文字列の描画にトライしてみてください!

また、text メソッドから利用されるフォントの設定方法については下記ページで詳しく説明していますので、フォントの設定方法について学びたい方はぜひ下記ページも読んでみてください!

Pillowのtextメソッドで描画する文字列のフォントやサイズの変更方法の解説ページアイキャッチ 【Pillow/Python】textメソッドで描画する文字のフォントやサイズを変更する

同じカテゴリのページ一覧を表示

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です