【iPhone】カレンダー画像を動的に生成するショートカット

今回は、カレンダー画像をショートカットで生成する方法についての紹介です。前記事で紹介した壁紙をランダムに切り替えるショートカット, オートメーションと組み合わせると、ランダムに切り替えた壁紙に対して指定月のカレンダー画像を動的に重ねるということが可能になります。

動作としては、以下のような感じです。まあカレンダーを重ねたものが壁紙として綺麗かどうかはちょっと微妙かもしれないですけれど。

動画その1

動画その2


1. ショートカットの取得

リンクは以下です。ちゃんと動作させるには5つ全て必要になるので注意してください。

genCalenHTML


genCalenImg


genCalenImgMask


genTransCalenImg


calenOnImg


2. カレンダー画像の生成

カレンダー画像を生成するには、genCalenImg もしくは genTransCalenImg を使います。後者のショートカットは背景をマスクした画像を作れるので、記事冒頭の 動画その2 のような用途で使えます。

使い方としては以下の通りです。ショートカット単体で使うのではなく、「ショートカットを実行」アクションを使って外から実行させます。入力として、辞書を使ってカレンダー画像生成に必要な情報を渡すと、それを使って画像を生成してくれます。

画像1

渡す辞書のサンプル(コピペ用)

{"year":2021,"month":8,"fontsize":7,"text":"white","bgcolor":"black","suncolor":"red","satcolor":"blue","wCropRatio":0.93,"hCropRatio":0.35,"radius":200}

※ もちろん、「辞書」アクションで値を渡してもよいです。

辞書で渡す各情報の説明を以下に載せます。

・year
生成するカレンダーの年情報です

・month
生成するカレンダーの月情報です

・fontsize
文字の大きさです。1〜7までの整数値です。基本的には7を渡すようにしてください。これを変更した場合、後述するwCropRatioとhCropRatioの値をそれぞれ調整する必要が生じます

・text
文字の色です。使える色の種類は、以下サイトなどを参考にしてください

・bgcolor
背景色です。textと同じように指定してください

・suncolor
日曜日の色を指定することができます

・satcolor
土曜日の色を指定することができます

・wCropRatio
生成したカレンダー画像の横の切り取り率です。仕様上、カレンダーは画像の左上に配置されているので、この値を0.1〜1の範囲で動かして、横幅を調整する必要があります

・hCropRatio
生成したカレンダー画像の縦の切り取り率です。wCropRatioと同様に指定します

・radius
角に丸みをつけたい場合、この値を1以上にしてください。0にすれば長方形のカレンダー画像が得られます


3. カレンダーを壁紙に重ねる

カレンダーを壁紙に重ねるには、calenOnImg を使います。

実行例を以下に示します。

レシピ例

画像2


生成される画像の例

画像3

※ calenOnImg に渡された壁紙画像は、お使いの端末の横幅と縦幅に自動的にリサイズされますので注意


calenOnImgには、辞書ではなくリストで情報を渡します。リストの1番目の要素は壁紙の画像、2番目はカレンダーの画像、3番目はカレンダーを表示する場所とその透明度の情報が入った辞書をそれぞれ指定します。

上の例のショートカットでは、変数"params"に対して順に「変数に追加」アクションを使って追加していくことで、リストを構築しています。

なおリスト3番目の辞書は、以下です。サンプルと説明を載せます。

辞書サンプル(コピペ用)

{"xLoc":0,"yLoc":0.2,"transparency":100}

・xLoc
カレンダーを置くx座標は、floor(端末の横幅 * xLoc)で計算されるので、その値を指定します。0〜1までの実数値です。

・yLoc
カレンダーを置くy座標は、floor(端末の縦幅 * yLoc)で計算されるので、その値を指定します。0〜1までの実数値です。

・transparency
カレンダーの不透過度です。0〜100までの値。


4. ランダム壁紙と組み合わせる

前記事で作り方を紹介したランダム壁紙のショートカットに少し手を加えることで、ランダムに設定した壁紙に対してカレンダー画像を追加するということが可能になります。(動作の様子は記事冒頭の動画を参照)

変更点としては、ランダムに設定される壁紙のサイズが端末の横幅と縦幅と同じになるようにするというだけです。レシピを以下に載せます。

画像4

備考

・端末の横幅, 縦幅を取得するには「デバイスの詳細を取得」アクションを使う

・画像のサイズ変更を行うには、「イメージのサイズを変更」アクションを使う


そうしたら、以下のような処理を順に行うショートカットを新規作成します。レシピとしては、[3. カレンダーを壁紙に重ねる] のものとほぼほぼ同じようになるかと思います。

(1) 変更したランダム壁紙(changeWallpaper)のショートカットを「ショートカットを実行」アクションで実行して壁紙をランダムに設定する。出力(設定された壁紙)を適当な変数に設定しておく。

(2) カレンダーの画像を生成する(genCalenImgもしくはgenTransCalenImg)。出力を(1)で定義した変数に追加する

(3) calenOnImg を実行するために、座標情報と不透明度の辞書を(1)で定義した変数に追加する。

(4) ランダム壁紙のショートカットの出力画像(設定した壁紙)に、(2)で生成したカレンダー画像をcalenOnImgを使って重ねる。入力として、(1)で定義した変数を渡す

(4) カレンダーを重ねた画像を壁紙に設定して終了


オートメーションから呼び出すようにすれば、毎日自動で実行させたりできるかと思います。それについての方法は前記事で紹介しているので、よければ参照してやってください。


5. 個々のショートカットの簡易説明

レシピの詳細には深くは触れませんが、概要だけここにまとめておきます。

・genCalenHTML
カレンダーのhtmlを生成します。実行例は以下のような感じになります。渡す情報は genCalenImg とほぼほぼ同じです。

画像5

辞書サンプル(コピペ用)

{"year":2021,"month":8,"fontsize":7,"text":"yellow","bgcolor":"black","suncolor":"red","satcolor":"blue"}

出力例

<body bgcolor="black" text="yellow">
<font size="7">
<tt>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2021&nbsp;&nbsp;8<br>
&nbsp;<font color="red">Sun</font>&nbsp;Mon&nbsp;Tue&nbsp;Wed&nbsp;Thu&nbsp;Fri&nbsp;<font color="blue">Sat</font><br>
<font color="red">&nbsp;&nbsp;1&nbsp;</font>&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;6&nbsp;<font color="blue">&nbsp;&nbsp;7&nbsp;</font><br><font color="red">&nbsp;&nbsp;8&nbsp;</font>&nbsp;&nbsp;9&nbsp;&nbsp;10&nbsp;&nbsp;11&nbsp;&nbsp;12&nbsp;&nbsp;13&nbsp;<font color="blue">&nbsp;14&nbsp;</font><br><font color="red">&nbsp;15&nbsp;</font>&nbsp;16&nbsp;&nbsp;17&nbsp;&nbsp;18&nbsp;&nbsp;19&nbsp;&nbsp;20&nbsp;<font color="blue">&nbsp;21&nbsp;</font><br><font color="red">&nbsp;22&nbsp;</font>&nbsp;23&nbsp;&nbsp;24&nbsp;&nbsp;25&nbsp;&nbsp;26&nbsp;&nbsp;27&nbsp;<font color="blue">&nbsp;28&nbsp;</font><br><font color="red">&nbsp;29&nbsp;</font>&nbsp;30&nbsp;&nbsp;31&nbsp;
</tt>
</font>
</body>

・genCalenImg
カレンダー画像を生成します。内部の処理の流れとしては、genCalenHTML を呼び出してその結果(html)からイメージを生成し、それをwCropRatio, hCropRatio, radiusの情報を使ってサイズ調整するという感じになっています。

・genCalenImgMask
genTransCalenImg のためのマスク画像を生成します。実行例は以下。渡す情報としては、genCalenImg と同じですが、ショートカット内でtextの値がwhiteに、bgcolorの値はblackに置き換わるので、常に文字が白で背景が黒の画像が生成されます。

画像6

・genTransCalenImg
カレンダー画像(透過画像版)を生成します。内部の処理の流れとしては、genCalenImgMask を実行してマスク画像を得、それを使ってカレンダー画像をマスクして、その結果を出力するという感じになっています。使い方は genCalenImg と同じです。ただ、radiusは0でいいんじゃないかなあと思います。

・calenOnImg
壁紙にカレンダーを重ねます。ショートカットの入力として、要素数が3のリストを渡す必要があります。リストの内容は

・1番目の要素は壁紙の画像
・2番目はカレンダーの画像
・3番目はカレンダーを表示する場所とその透明度の情報が入った辞書

となります。


6. カレンダー生成アルゴリズム

genCalenHTML の内部の処理の流れについて、ここに簡単にですがまとめておきます。なお、空白の出力とかは省略してます。

(1) カレンダーの年と月の情報を出力して改行します
 例) 2021 8

(2) カレンダーの曜日情報(Sun Mon Tue Wed Thu Fri Sat)を出力して改行します

(3) 出力するカレンダーの月の1日目の曜日が、日曜日からどれだけ離れているかを求めます

(4) (3)で求めた数 * 4 個分くらいの半角スペースを出力するなりして、間隔を空けます。

(5) 出力するカレンダーの月の日数を求め、その数だけ(6)と(7)の処理を繰り返します。iを繰り返しのインデックスとします。iは1〜月の日数まで繰り返す度に増えるとします。

(6) iを出力します

(7) 出力したiが何曜日なのかを求め、もし土曜日なら改行を出力します


7. ショートカットTips

ショートカットの中で、日付関係で使っているテクニックなどをまとめておきます。

・月の日数を求める
素直なやり方としては、予め辞書などに月の長さを登録しておいて、月の情報からその長さを取得できるようにするというのが考えられます。(ただし、2月は閏年を考慮する必要あり)

もう一つのやり方は、「日付を調整」アクションと「日付間の時間を取得」アクションを上手く使ったやり方です。各月の1日の日付と、それに1ヶ月加算した日付の間がどれだけ日が空いているかというのを求めることで、結果的に月の長さを得ることができます。レシピ例を以下に載せます。

画像7


・曜日を数字に変換
日付のカスタムフォーマットを使って、'e'の一文字を指定するだけです。日曜日は1に、月曜日は2に、...土曜日は7に、と順に変換できます。日付をフォーマットするやり方は、過去記事などを参照してください。

・日曜日からどれだけ離れているか計算
上の方法で曜日を数字に変数した後、以下の式を「計算式」アクションを使って計算すれば良いです。

fabs(1 - フォーマット済みの日付)

・辞書を使ってショートカットに情報を渡す
ショートカットにある程度の量の情報を一気に渡したい場合、辞書アクションを使うやり方が使えます。過去記事にやり方が書いてあるので良ければ参照してください。

・「辞書」アクションのコピペ
実はアクションはショートカット間でコピー & ペーストすることができます。これを使うことで、前に定義した辞書アクションの再利用などが簡単に行えます。これもまた過去記事にやり方が書いてあるのでよければ参照してください。


8. テキスト画像のマスクについて

今回はカレンダー画像専用(genCalenImgMask, genTransCalenImg)にしてますが、以下のようにすれば汎用的なものが作れるのではないかなと思います。試してはないので色々不安定な感じですけれど。

(1) 出力したい文字を入力

(2) 入力した文字を入れたhtmlを2種類作る

・好きな文字色・フォントのもの
・上のhtmlに対して、文字色は白、背景を黒にしたもの

(3) 2つのhtmlからイメージをそれぞれ作る。イメージを作るには、「HTMLからリッチテキストを作成」アクション,「pdfを作成」アクション, 「入力からイメージを取得」アクションの順に呼び出す

(4) 文字色が白、背景を黒にした方をマスクとして、マスクする。マスクには「イメージをマスク」アクションを使います


9. まとめ

今回はカレンダー画像をショートカットを使って動的に生成する方法について紹介しました。

主な用途としては、ロック画面の壁紙に対して適応するというのがいいんじゃないかなあと思います。

あとはまあ、プレビューなしで設定させる場合は、元の横幅と縦幅を無理やり引き伸ばしたりするので、見た目的にそれはどうなんだという感じもしたりしますが、それはなんとも。

ただ、パラメタをいじれば色々なカレンダー画像が簡単に作れるのはけっこういいかなあと。genCalenHTMLをいじれば、日本語版カレンダー(日 月 火 水 木 金 土 日)とかにもできるかと思います。多分

では今回はこの辺で。

この記事が気に入ったらサポートをしてみませんか?