【Pythonでサムネ制作①】PILで画像の上に文字を重ねて中央表示
ブログやYouTubeで使うサムネを、画像編集ソフトを使わずにプログラミングでサクッと制作できたらいいですよね! とくに私なんかは、このブログサイトのアイキャッチ画像をPythonで制作できたら最高と思うのです。
さて、続編があるかどうかわかりませんが、Pythonでサムネ制作の第一弾としまして「画像の上に文字を重ねて中央表示する」をやってみました。
普段の作業が大幅に短縮できそうです。クリエイター&プログラマーの方必見の内容です!
ゴール
こんな感じのベースとなる画像を用意しまして、、、
それがこうなることを目指して進めていきます!
ちなみにCSSでテキストを重ねるやり方もあります。詳しくはこちらをご覧ください。
つかうもの
Python3をご用意ください。
Pillow
また、Pillow(PIL)という画像処理によく使われるモジュールが必要です。pipなどでインストールしておきましょう。
Pillow is the friendly PIL fork by Alex Clark and Contributors. PIL is the Python Imaging Library by Fredrik Lundh and Contributors.
Pillow (PIL Fork) 9.2.0 documentation
Pillowのインストール
$ pip3 install Pillow
画像の上に文字を表示
それではさっそく、画像の上に文字を表示してみます。 次のようなプログラムを作成し実行してみてください。
from PIL import Image,ImageFont,ImageDraw
image_path = 'fuji.jpg' # 文字を重ねる画像
out_path = 'a.jpg' # 出力先
font_path = '/System/Library/Fonts/ヒラギノ角ゴシック W5.ttc'
font_size = 100
font_color = (255,255,255) #文字の色
text = '新倉山浅間公園'
pos = (200,100)
font = ImageFont.truetype(font_path, font_size)
image = Image.open(image_path)
draw = ImageDraw.Draw(image)
draw.text(pos, text, font=font, fill=font_color)
image.save(out_path)
するとこうなります。画像の上にテキストが表示できましたね!
お使いのOSによってフォントの種類や場所は違います。私はmacOSですので、フォントの場所は次のようになってます。
macOSのフォントの保存場所
macOSのフォントの保存場所は主に次の3つです。
- /System/Library/Fonts
- /Library/Fonts
- /Users/ユーザ名/Library/Fonts
フォントが多すぎると画像編集ソフトでいちいち迷うので、使わないフォントは削除するようにしてますが、それでもこれだけたくさんの種類がインストールされてます。
$ ls /System/Library/Fonts/
Apple Braille Outline 6 Dot.ttf NotoSansKannada.ttc
Apple Braille Outline 8 Dot.ttf NotoSansMyanmar.ttc
Apple Braille Pinpoint 6 Dot.ttf NotoSansOriya.ttc
Apple Braille Pinpoint 8 Dot.ttf NotoSerifMyanmar.ttc
Apple Braille.ttf Optima.ttc
Apple Color Emoji.ttc Palatino.ttc
Apple Symbols.ttf PingFang.ttc
AppleSDGothicNeo.ttc SFArabic.ttf
AquaKana.ttc SFCompact.ttf
ArialHB.ttc SFCompactItalic.ttf
Avenir Next Condensed.ttc SFCompactRounded.ttf
Avenir Next.ttc SFNS.ttf
Avenir.ttc SFNSItalic.ttf
Courier.ttc SFNSMono.ttf
GeezaPro.ttc SFNSMonoItalic.ttf
Geneva.ttf SFNSRounded.ttf
HelveLTMM STHeiti Light.ttc
Helvetica.ttc STHeiti Medium.ttc
HelveticaNeue.ttc Supplemental
Hiragino Sans GB.ttc Symbol.ttf
Keyboard.ttf Thonburi.ttc
Kohinoor.ttc Times.ttc
KohinoorBangla.ttc TimesLTMM
KohinoorGujarati.ttc ZapfDingbats.ttf
KohinoorTelugu.ttc ヒラギノ丸ゴ ProN W4.ttc
LastResort.otf ヒラギノ明朝 ProN.ttc
LucidaGrande.ttc ヒラギノ角ゴシック W0.ttc
MarkerFelt.ttc ヒラギノ角ゴシック W1.ttc
Menlo.ttc ヒラギノ角ゴシック W2.ttc
Monaco.ttf ヒラギノ角ゴシック W3.ttc
MuktaMahee.ttc ヒラギノ角ゴシック W4.ttc
NewYork.ttf ヒラギノ角ゴシック W5.ttc
NewYorkItalic.ttf ヒラギノ角ゴシック W6.ttc
Noteworthy.ttc ヒラギノ角ゴシック W7.ttc
NotoNastaliq.ttc ヒラギノ角ゴシック W8.ttc
NotoSansArmenian.ttc ヒラギノ角ゴシック W9.ttc
$ ls /Library/Fonts/
Arial Unicode.ttf BROOKH2.ttf BauhausBoldItalic.ttf BauhausRegular.ttf
BAUHHL.ttf BauhausBold.ttf BauhausItalic.ttf
$ ls /Users/mopipico/Library/Fonts/
07にくまるフォント.otf YAKITORI.TTF
AoyagiKouzanTOTF.otf aoyagireisyosimo_otf_2_01.otf
HalfFont-Regular.ttf gomarice_mukasi_mukasi.ttf
KsoKagerou.otf mokkumokumo.ttf
KsoKagerouN.otf pupupu-free.otf
KsoTouryu.otf 瀞ノグリッチ黒体H1.otf
KsoTouryuN.otf 瀞ノグリッチ黒体H2.otf
NikkyouSans-mLKax.ttf 瀞ノグリッチ黒体H3.otf
SeimeiKana-Free.otf 瀞ノグリッチ黒体H4.otf
フォントのタイプ
フォントのタイプは大雑把に次のとおりです。
拡張子 | 意味 |
---|---|
.ttf | TrueTypeフォント |
.otf | OpenTypeフォント |
.ttc | TrueTypeフォントを1つのファイルにまとめたもの |
.otc | OpenTypeフォントを1つのファイルにまとめたもの |
他にもフォントタイプには、ウェブブラウザでよく使われるeot, woff, woff2などがあります。
画像の「中央」にテキストを表示したい
先ほどのプログラムでは位置を自分で指定しなければなりませんでした。これだと画像の「中央」にテキストを表示したい場合に具合が悪いです。 そこで画像サイズとテキストの縦横幅を取得して、計算して「中央」にテキストを表示できるようにしてみました。
from PIL import Image,ImageFont,ImageDraw
image_path = 'fuji.jpg' # 文字を重ねる画像
out_path = 'b.jpg' # 出力先
font_path = '/System/Library/Fonts/ヒラギノ角ゴシック W5.ttc'
font_size = 100
font_color = (255,255,255) #文字の色
text = '新倉山浅間公園'
font = ImageFont.truetype(font_path, font_size)
image = Image.open(image_path)
draw = ImageDraw.Draw(image)
(font_w, font_h), (offset_x, offset_y) = font.font.getsize(text)
img_w, img_h = image.size
print("{},{},{},{}".format(font_w, font_h, img_w, img_h))
pos = ((img_w - font_w) / 2, (img_h - font_h) / 2)
draw.text(pos, text, font=font, fill=font_color)
image.save(out_path)
はい。いいかんじでキレイに画像の中央にテキストを表示できましたね。
この部分でフォントの縦横幅を取得しているのがポイントです。
(font_w, font_h), (offset_x, offset_y) = font.font.getsize(text)
img_w, img_h = image.size
python - How to get the font pixel height using PIL's ImageFont class? - Stack Overflow
【おまけ】テキストに枠線をつけたい
さいごに、テキストの枠線を表現できたら良いですよね?borderとかstroke、outlineとか呼び方はさまざまありますが、よく使われるアレです。
枠線を処理するにはこんな感じのプログラムでいけちゃいます。
from PIL import Image,ImageFont,ImageDraw
image_path = 'fuji.jpg' # 文字を重ねる画像
out_path = 'c.jpg' # 出力先
font_path = '/System/Library/Fonts/ヒラギノ角ゴシック W7.ttc'
font_size = 100
font_color = (255,255,255) # 文字の色
stroke_color = (33, 33, 33) # 枠線の色
text = '新倉山浅間公園'
stroke_width = 10
font = ImageFont.truetype(font_path, font_size)
image = Image.open(image_path)
draw = ImageDraw.Draw(image)
font_w, font_h = font.getsize(text, stroke_width=stroke_width)
img_w, img_h = image.size
print("{},{},{},{}".format(font_w, font_h, img_w, img_h))
pos = ((img_w - font_w) / 2, (img_h - font_h) / 2)
draw.text(
pos, text,
font=font,
fill=font_color,
stroke_width=stroke_width,
stroke_fill=stroke_color)
image.save(out_path)
デザイン性はともあれ、なんとか枠線がつきました!
いかがだったでしょうか? Pillowを使って簡単に画像に文字を重ねることができました。この他にも画像に画像を重ねたり、図形を描画したりもできるはずです。 ▼ 続きの「Pythonでサムネ制作 第二弾」を追記しました!