前回、透け感のあるサムネイルを作ることに集中しすぎて、文字サイズを気にしていませんでした。
文字サイズは「ImageFont.truetype()」で指定できるけれど、これを自動でやってくれたらいいのになぁ。
ライブラリ「Pillow」公式ドキュメントのリファレンスを眺めていたら、ちょうど良いメソッドがあったので、早速使ってみました。
準備するものは?
今回も、ライブラリ「Pillow」を使います。
使うメソッドは?
「ImageDraw.textsize()」です。
フォントの種類とサイズを指定すると、描写した時のサイズを「単位:ピクセル」で返します。
戻り値はタプルで、(x,y)の順で格納されます。
この戻り値が、希望の数値になるまでループすれば良い、というわけです。
コードの書き方は?
前回のコードに文字サイズを調整するループを書き加えました。
画像の幅80%に文字を収めるように自動調整します。
from PIL import Image, ImageFont, ImageDraw
txt = 'Pythonで文字サイズを自動調整する'
# txt = 'Python'
# 画像ファイルを読み込み、「RGBA」に変換する
photo_img = Image.open('test.jpg').convert('RGBA')
img_size = photo_img.size
# 透過ボックス作成
a = Image.new('RGBA',img_size)
draw_img = ImageDraw.Draw(a)
draw_img.rectangle(
[(0, img_size[1] / 3), (img_size[0], img_size[1] * 2 / 3)],
fill = (255, 220, 0, 128)
)
# フォントは源ノ角ゴシック
font = r'C:/Windows/Fonts/SourceHanSans-Heavy.otf'
i = 1
# 画像幅の80%を超えるまでループ
while draw_img.textsize(txt,ImageFont.truetype(font, i))[0] < img_size[0] * 0.8 : i += 1
# 文字入れ
draw_img.text(
(img_size[0] / 2, img_size[1] / 2),
txt,
fill = 'black',
font = ImageFont.truetype(font , i - 1),
anchor = 'mm',
)
# 合成
out_img = Image.alpha_composite(photo_img,a)
# jpgファイルで保存するなら「RGB」に変換
out_img = out_img.convert('RGB')
# 保存
out_img.save('test2.jpg')
実行結果は?
見事に収まっています。
ちなみに、コメントアウトした「txt = 'Python'」の方を実行したのはこちら
こちらも調整されて文字入れができています。
大きすぎて下地からはみ出してしまいました。
「ImageDraw.textsize()」の戻り値「y」も参照しながら調整するか、下地のサイズを変更するか、いずれにせよ改良が必要ですね。
まとめ
画像に入れる文字サイズを自動調整するには、「ImageDraw.textsize()」の戻り値を見ながらループします。
フォントのサイズが同じでも、種類が違うと描写されるサイズが変わってくるのはよくある話。
ちょうど良いメソッドがあり、自動調整できるようになったので良かったです。
Pythonライブラリ「Pillow」の投稿まとめ