iOSのショートカットアプリで写真をコルクボードに貼ってみる

お初にお目にかかります、カヤックアキバスタジオでエンジニアをやっている中島です。

こちらは 面白法人グループ Advent Calendar 2022  の21日目の記事です。

本記事では、iOSのショートカットアプリで「コルクボードに写真を貼り付けたような画像」を作成するショートカットを作成してみようと思います。

ゴールのイメージはこんな感じです。

iOSのショートカットアプリとは

あらかじめ用意された様々なアクションをつなぎ合わせることで操作の自動化が可能なiOSアプリです。

  1. 端末内の写真を選択し
  2. 画像のサイズを調整し
  3. メーラーを起動して添付する

みたいなことを一つの操作として実行できるようになります。多分。

iOSを操作するための具体的なアクション(写真を選択するなど)の他に制御構文的なパーツ(分岐やループ)が揃っているので、プログラミングに近い感覚で触れることができると思います。

詳しくは ショートカット ユーザガイド - Apple サポート (日本) を。

プログラマ向け?のショートカット解説

私もこの記事を機会に初めてショートカットを触ったわけなのでおかしなところもあるかもしれませんが、あらかじめ把握しておくと良いであろうことを並べてみます。

ショートカットにおける変数の扱い

これが一番重要だと思います。逆にいうとこれさえ把握しておけば、そんなにはまることもないと思います。

ショートカットにおける変数は一般的なプログラムの変数とは少し違い、常にリストです。 変数と聞くとまず

var hoge = "2022";

こういうものをイメージすると思います。(私がよく使用しているc#的な記載)

しかし、ショートカットにおける変数をc#で書くと

var hoge = new List<object>{ "2022" };

このようなイメージであるようです。

変数に値を設定するためのアクションには以下二つがあります。

使用例

これを同じくコードで表してみると

List<object> hoge;

// 変数に追加 (1回目)
if (hoge == null) hoge = new List<object>();
hoge.Add("2022");
// 変数に追加 (2回目)
if (hoge == null) hoge = new List<object>();
hoge.Add("2023");

// 変数を設定 (初期化したリストに新たに値を設定する)
hoge = new List<object>();
hoge.Add("2022");

となります。

分岐

分岐については if文 というそのままのアクションが用意されています。

使用例

これは

var hoge = new List<object>() { 2022 };
if ((int)hoge[0] == 2022) {
    Console.WriteLine("真でした");
} else {
    Console.WriteLine("偽でした");
}

という感じになるかと思います。
注意点として、変数 ほげ にさらに変数を加えた場合も、if文に渡した場合は最初の要素が参照されるようです。
(他のアクションにおいても、そのアクションが入力を一つしか取らない場合には最初の要素が参照されることが多いようです)

ループ

ループには

  • 繰り返す
  • 各項目を繰り返す

の2種類が用意されています。

繰り返す は指定した回数のループなので割愛、各項目を繰り返す をみてみます。

例によってc#的に表してみると

List<object> hoge;

// 変数に追加 (1回目)
if (hoge == null) hoge = new List<object>();
hoge.Add("今年は2022年です");
// 変数に追加 (2回目)
if (hoge == null) hoge = new List<object>();
hoge.Add("来年は2023年です");

// ループ
foreach (var huga in hoge) {
    Console.WriteLine(huga);
}

となります。 ショートカットにおける変数は常にリストなので、アクション 各項目を繰り返す に直接渡すことが可能です。

関数

ショートカットでは別のショートカットの呼び出しが可能です。

故に関数のような表現が可能です。
I/Oはどちらも変数(つまりリスト)一つのようなので、若干強引ですが複数の要素を渡したり呼び出し元に返したりすることができます。

List<object> hoge;

if (hoge == null) hoge = new List<object>();
hoge.Add("2022");
if (hoge == null) hoge = new List<object>();
hoge.Add("2023");

var result = Test(hoge);

Console.WriteLine(result[0]);


public List<object> Test(List<object> input){
    // do something
}

「コルクボードに写真を貼り付けたような画像」を作成するショートカット

では実際にショートカットを作成します。

方針

あらかじめ用意されたアクションに イメージを重ねて表示 というものがあります。
これは画像Aと画像Bを渡すことで、画像Bの上に画像Aを重ねた画像Cを返してくれるというアクションです。
これを利用し

  1. ユーザーにベースの画像を選択してもらう(コルクボード風の画像など)
  2. ユーザーにその上に重ねたい画像を複数枚選択してもらう(写真など)
  3. [2]で選択してもらった画の枚数をもとに縦横の分割数や画像のサイズを決定する
  4. イメージを重ねて表示 を枚数分繰り返す

このようにすることでそれらしい動作になるはずです。

実際に作ったもの

...長いですね。
大枠の方針は前述の通りですが、貼り付ける画像に縁をつけたり画像の位置や角度を少しランダムに変えてみたりしています。
出力はこんな感じです。

一応それっぽくはなったかなーと思います。
枚数に対するグリッド化の処理などが適当すぎて枚数によってはとてもひどいことになります。

作ってみての感想

感想をざっくり書いてみます

ポジティブな面

  • あらかじめ用意されているアクション群が豊富なので思いの外いろいろできそう
  • iOS向けになにか自分用のアプリを用意しようと思うとApple Developer Programへの加入などハードルが高いが、これなら気軽に作れる
  • プログラミングに初めて触れたときのような、自分のやりたいことが実現できたことに対する感動が得られる
  • スクリプト的なものをねそべりながらぽちぽち作成できるのが新鮮
  • 制御構文などが用意されているので「プログラミングってこういう感じです」というのを教えるのに良いかもしれない?iPhoneだけあれば試せる
  • アイデア次第でiOSアプリ開発時のワークフローの改善に役立てることができるかもしれない

ネガティブな面

  • 操作性の問題で長大なものを作成しようとすると辛い。mac(PC)上で編集できるエディタとかがほしくなる

おわりに

ここまでお付き合い頂き、ありがとうございました!
ショートカットの共有リンクを作成してみたので、もしよかったら使ってみてください。