--- title: PythonでGoogleカレンダーのfaviconみたいな画像をたくさん生成してVueのプロジェクトに組み込んでみた tags: Python PIL colaboratory Vue.js author: maroKanatani slide: false --- この記事は[株式会社クロノス](https://www.kronos.jp/)の[「~2020年春~勝手にやりますアドベントカレンダー」](https://qiita.com/beeeyan/items/342d51fa301bcf81e9c0)の19日目の記事です。 # はじめに Googleカレンダーのfaviconをご存知でしょうか? ![スクリーンショット 2020-03-15 17.56.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239351/d0d52489-3697-771e-5e0f-58230f2ec592.png) この画像は3月15日に取った画像ですが、実はアクセスした日によって中の数字が変わる仕組みになってたりします。 ということで自分も[前にカレンダー的なアプリを作った](https://qiita.com/maroKanatani/items/7ca85205430cead76817)のでそれに導入してみることにします。 前まではこんな感じでした。 ![スクリーンショット 2020-03-15 17.59.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239351/d828008c-1f3b-9387-1a01-acda8bfcf5c0.png) はい、デフォルトです。 めっちゃ**Vue.jsで作ってます!!!!**っていうのが伝わる感じになっていますね。 技術のアピールは大事ですが、アプリとしては若干かっこ悪いので修正してみます。 開発者ツールでGoogleカレンダーを見てみると、1〜31まで全パターンのfaviconを用意しているみたいなので、Googleにならって全パターン用意して表示を切り替えるような感じにしてみます。 # 画像を用意する ## 使用したツール等 - Google Colaboratory - Python 3.6.9(Colaboratoryに入ってたバージョン) - PIL(Python Image Library) - ICOOON MONO(アイコン) ## ベースとなる画像を用意する 今回はICOOON MONOにあるカレンダーのアイコンに数字を重ねて画像を生成してみます。 [こちら](https://icooon-mono.com/12567-%E3%82%AB%E3%83%AC%E3%83%B3%E3%83%80%E3%83%BC%E3%81%AE%E3%83%95%E3%83%AA%E3%83%BC%E3%82%A2%E3%82%A4%E3%82%B3%E3%83%B320/)のアイコンを使用させていただきました。 ![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239351/5fea8f09-b3bd-2035-6404-9fd3fa8b3374.png) サイズは48×48、カラーはアプリのテーマに合わせて紫(rgb(121, 88, 214))にしました。 ## Colaboratoryを開く 以下の画像のような状態にします。 ![スクリーンショット 2020-03-15 18.23.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239351/57278a27-b952-8c3a-633b-6cda9081d8a1.png) まずベース画像をアップロードします。今回はbase.pngという名前でアップロードしました。 次に加工後の画像を格納するフォルダを作成します。今回はoutというフォルダを作成しました。 以上の準備ができたらPythonのコードを書いていきます。 真ん中に数字を配置するためにちょっとトリッキーなことやってたりします。 ```python:画像を合成するコード from PIL import Image # 各種設定 IMAGE_WIDTH = 48 IMAGE_HEIGHT = 48 THEME_COLOR = (121, 88, 214) # 1〜31までループして作成する for i in range(1, 32): # faviconに表示する数字 i_str = str(i) # Font名、サイズを設定する fnt = ImageFont.truetype('LiberationMono-BoldItalic', 25) # 数字を配置する場所を計算するために文字の横幅、縦幅を取得する w, h = fnt.getsize(i_str) # ベースの画像を読み込む im = Image.open('./base.png') draw = ImageDraw.Draw(im) # 読み込んだ画像にテキストを合成する draw.text( # こう書くと真ん中に配置できるみたい(高さだけ3px微調整してます) xy=((IMAGE_WIDTH - w) / 2, (IMAGE_HEIGHT - h) / 2 + 3 ), text=i_str, fill=THEME_COLOR, font=fnt ) # 保存 ./out/favicon01.pngみたいなファイル名にしています im.save("./out/favicon{}.png".format(i_str.zfill(2))) ``` ちなみにフォントは好きなものをダウンロードしてCalaboratoryにアップロードすれば使えるようになりますが、以下のコードを実行すると組み込まれているフォントを確認できます。 今回は数値を扱うだけだったので組み込みのものを使用しました。 ```python:Colaboratoryのフォントを確認するコード import subprocess res = subprocess.check_output("fc-list") print(str(res).replace(":", "\n")) ``` 上手く行けばoutフォルダ内に以下のような画像が生成されるはずです。 ![favicon01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239351/a999e52b-8fd5-222d-890b-c9f89aefd216.png) outフォルダ内の画像をダウンロードしましょう。 Colaboratoryだとフォルダ丸ごとダウンロードできなさそうなので 以下のコードでzipにしておくと楽にダウンロードできます。 ```python:outフォルダをzipに固める import shutil shutil.make_archive('./out', 'zip', root_dir='./out') ``` # Vueのプロジェクトに組み込む Vueのプロジェクトのpublicフォルダ内に生成した画像を配置しましょう。 index.htmlを修正します。 faviconを設定しているlinkタグのhref属性を書き換えるscriptを追加します。 ```html:index.html <%= htmlWebpackPlugin.options.title %>
``` いい感じになりました。(満足) ![スクリーンショット 2020-03-15 18.56.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239351/2012ee2a-d80f-2909-b3ce-dfc1ac2453af.png) あとはビルドして本番環境にデプロイです。 めでたしめでたし・・・ ## と思いきや・・・ 次の日(16日)にアクセスしてみると、アイコンが15から変わってないじゃないですか。 なんでや…!と思い、トランスパイルされたindex.htmlを見てみると ```html:dist/index.html ad-calendar
``` なんとビルドを実行した日付に固定されてしまってますね。 index.html内でJavaScriptのテンプレート記法を使うと実行時の値に固定されてしまうっぽいです。 最終的には以下のように修正すると期待通り動作するようになりました。 ```html <%= htmlWebpackPlugin.options.title %>
``` [今度こそいい感じになりました。(満足)](https://ad-calendar-992c5.firebaseapp.com/) # 参考 https://qiita.com/agajo/items/90a29627e7c9a06ec24a https://www.tech-tech.xyz/drawtext.html https://icooon-mono.com/license/ https://stackoverflow.com/questions/1970807/center-middle-align-text-with-pil