Pythonの「Pillow」を使ってSlackの文字絵を作る

皆さんは、「赤かぶら漬け」なる漬物をご存知でしょうか。
要は赤かぶの漬物なのですが、岐阜県の飛騨高山地方では主に「 赤かぶを 塩漬けした漬物 」を指します。

▲ これより3倍速そうなかぶです

東京では赤かぶら漬けを扱っている店舗がほとんど無く、久々に赤かぶら漬けロスに陥っていた私でしたが、この間偶然にも「飛騨高山物産展」を見かけて物凄い勢いで赤かぶら漬けを衝動買いしてしまいました。
改めて食べると「かぶ」そのものの特徴的な風味も、ご飯を食べたくなる強めな塩気も何もかもが好みなんですよね。大人になった今なら日本酒とかと食べたら尚美味しいなと新たに考えるようになったり。
この美味しさをシェアするにはここしかない、と感じてついつい語ってしまいました。
AWS事業本部のShirotaです。岐阜と言えば、そろそろ栗きんとんも美味しい季節になりそうですね。

漬物と違ってSlackの絵文字はあっさり作りたい派

さて、そんな漬物が好きな私ですが、赤かぶら漬けと同じくらい好きなのは「 Slackの文字絵(文字の絵文字)を作成する事 」です。
スピーディーかつ的確な想いを伝えられる点においてリアクションを押すのが大好きなので、伝えたい言葉が絵文字一覧に無かった時にはすぐに文字絵を作成してしまいます。

▲ しょうもないものも多い。が、なんやかんやで結構使っている

今まで、文字絵を作成したい際には MEGAMOJI という便利なサイトでささっと作成していたのですが、アニメーションがついていないシンプルな文字絵文字を作成したい時にもう少し手軽にやれないものかなと思うようになりました。
「こう、スタタターンと CLI1行で瞬殺できるような アレが欲しいな……」と。
後、個人的趣味なのですが私はフォントが大好きなので、自分の好きなフォントで文字絵を作成したいなと思う事が度々ありました。
そこで、Pythonのライブラリ「Pillow」を使って簡単2文字×2文字絵が作成出来るようなスクリプトを作ってみました。

やりたい事と前準備

やりたい事

まず、今回Pythonでやりたい事をまとめます。

  • 好きな2文字×2文字の計4文字を画像にする
  • 画像の背景は透明にする
  • 文字色は指定できる範囲の任意の色にする
  • 画像はpngファイルにする
  • フォントは前もって用意(フリーフォント)し、スクリプト内で指定しておく

前準備

今回、やりたい事を実現する為に以下の環境を用意しました。

  
$ pyenv versions
  system
* 3.7.3 (set by /Users/Shirota/Documents/mojiemoji/.python-version)
$ pip3 install Pillow
Collecting Pillow
  Downloading https://files.pythonhosted.org/packages/8f/f3/c6d351d7e582e4f2ef4343c9be1f0472cb249fb69695e68631e337f4b6e9/Pillow-6.1.0-cp37-cp37m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl (3.8MB)
    100% |████████████████████████████████| 3.9MB 1.2MB/s
Installing collected packages: Pillow
Successfully installed Pillow-6.1.0  

それぞれバージョンは

  • Python 3.7.3
  • Pillow 6.1.0

です。
Pillowとは、Pythonの画像処理ライブラリです。
かつてPythonではPIL(Python Imaging Library)という画像処理ライブラリがあったのですが、こちらは2011年に開発が停止してしまっています。
このPILのリポジトリをフォークして開発を引き継いだのがPillowであり、Python3への対応をやってくれています。
既存の画像の編集のみでなく新規に画像を作成できると知ったので、今回はPillowを使ってみる事にしました。
後、今回は以下のフリーフォントを事前に用意しておきました。

源柔ゴシック (げんじゅうゴシック)

実際にやってみたところ、フォント規格はTrueType(.ttf)でもOpenType(.otf)でも作成可能でした。
ただ、複数のフォントファイルを収納している .ttc.otc だと作成できなさそうでした。

▲ 余談ですが、センスが最高だと思っているフォントがこちら

作ってみた

実際に作ってみたスクリプトがこちらです。

  
# -*- coding: utf-8 -*-
from PIL import Image,ImageDraw,ImageFont
import sys
# 絵文字にしたい文字を入れる引数を定義
arg = sys.argv
imgname = arg[1]+arg[2]+'.png'
len_1 = arg[1]
len_2 = arg[2]
# 透明な256×256pxの画像を生成する
img = Image.new('RGBA', (256, 256), (0,0,0,0))
# 使用したいフォントの絶対パス、フォントサイズを指定する
fontcustom = ImageFont.truetype('~/Library/Fonts/GenJyuuGothicX-Heavy.ttf', 124)
# フォントカラーを引数から指定する
fontcolor = arg[3]
textd = ImageDraw.Draw(img)
# 2文字×2文字の引数が来たらテキストを描画する
if len(len_1) == 2:
    textd.text((0, -25), arg[1], fill=fontcolor, spacing=5, align='center', font=fontcustom)
else:
    print("1行目の文字数は大文字2文字にして下さい")
    sys.exit()

if len(len_2) == 2:
    textd.text((0, 105), arg[2], fill=fontcolor, spacing=5, align='center', font=fontcustom)
else:
    print("2行目の文字数は大文字2文字にして下さい")
    sys.exit()

# 「引数1+引数2」というファイルをpng形式で保存する
img.save(imgname)
print("Save "+ imgname)  

使ってみた

上記のスクリプトを使ってみました。

  
$ python3 ./mojiemoji-edit.py 魑魅 魍魎 black
Save 魑魅魍魎.png  

実際にできた文字絵画像はこんな感じです。かわいいです。

▲ 長時間見ていないのにゲシュタルト崩壊が起きました

ちなみに、今回はフォントとフォントサイズ・フォントの表示位置を固定している為、2文字以外の文字を引数にしているとエラー処理となるようにしています。

  
$ python3 ./mojiemoji-edit.py ガチャ 天井 black
1行目の文字数は大文字2文字にして下さい  
  
$ python3 ./mojiemoji-edit.py 宇宙 方程式 black
2行目の文字数は大文字2文字にして下さい  

3つ目の引数では、文字列でもカラーコードでも色を指定できます。
使用できる文字列は、以下のスクリプトを実行すると取得する事ができるので、参照してみて下さい。

# -*- coding: utf-8 -*-
from PIL import ImageColor

for i in sorted(ImageColor.colormap.items()):
    print(i)

カラーコードで指定する場合は、カラーコードをシングルクォーテーションで囲み文字データとして使用します。

$ python3 ./mojiemoji-edit.py おこ のみ '#cf0141'
Save おこのみ.png  

実際にできた文字絵画像はこんな感じです。

▲ 好みドンピシャの色でできた

今後やっていきたい事

今回はPillowを用いて、爆速でお好みカラー・お好みフォントで4文字画像を生成できるスクリプトを作成してみました。

試行錯誤しつつでしたが、実際にワンライナーで画像が生成できると嬉しいし、ますますSlack用の文字絵作成欲が湧いてきました。
折角なので、もっと色々な事ができるようになりたいなぁと考えています。

例えば、

  • 文字数に合わせて適切なフォントサイズ・文字幅を調整できるようにする
  • アニメーション文字の作成ができるようにする
  • Slackコマンドでこのスクリプトを実行できるようにする

といった事をやってみたいです。
今までプログラミングってやってみたいなと思いつつ、どんな成果物が欲しいかと言われると想像力が乏しく中々発想が浮かばなかったので、中々チャレンジできていませんでした。(学部時代に音楽ゲームが作ってみたい!と思いノー知識でC++に挑戦して爆発四散した過去があります)
自分はやりたい事があると自然と調べて書くんだな と今回改めて感じたので、折角見つけたやりたい事を大事にしつつ、これからもこういった活動に挑戦していきたいなと思います。

▲ 作って使ってみました