SNS上に写真をアップするとき,個人情報保護のため,人物の顔に絵文字で上記のようなマスキング処理を施すことがよくあります。そこで,次の条件を満たすシェルスクリプトを作ることを目指します。
要件
- macOS のデフォルト状態で動作する。ユーザに対して,事前に何らかのツールをインストールしておくなどの準備を要求しない。
- コマンドラインから使えるシェルスクリプトとする。
- 指定された絵文字を上から貼り込むことで人物の顔をマスキングする。写真の中に複数人が写っている場合にも対応。
- 処理結果はJPEGファイルとして出力する。
実装のアイデア
macOS には,顔認識エンジンが Vision フレームワークというAPI群で提供されています。これを自作プログラムから呼び出せばよいのですが,Swift や Objective-C のコードとして書くと,どうしても一度 clang でコンパイルする必要があり,シェルスクリプトとしては使えません*1。そこで,AppleScriptObjC のコードとして書き,それを /usr/bin/osascript
の引数として与えるのです。
いきなり完成形のシェルスクリプトを書くのは大変なので,まずは最も書きやすい Swift で Vision フレームワークを呼び出すコードを書いておいて,それを
と次々に書き換えてゆきます。
この手法は,以前PDFの結合やQRコードの生成,OCR処理などにも用いました。
完成形のシェルスクリプト
使い方
$ ./maskFaces.sh input.jpg output.jpg
とすると,input.jpg
の顔部分を 😂 という絵文字でマスキングした画像を output.jpg
として出力します。入力ファイルは,*.jpg
, *.png
, *.heic
など,macOSが標準で読めるファイル形式ならばOKです。出力ファイルはJPEG形式となります。
オプション
--emoji <EMOJI>
:顔の上に貼り込む絵文字を指定(デフォルト:😂
)--compression <VALUE>
:出力するJPEG画像の圧縮率を0.0
~1.0
の値で指定。1.0
だと無圧縮,0.0
だと最大圧縮。(デフォルト:0.8
)--dpi <VALUE>
:出力するJPEG画像のdpi値を指定(デフォルト:72
)
サンプル
入力ファイル
サンプルとして使えそうな適当な写真が見つからなかったので,画像生成AIで架空の人物写真を生成させました(ちょうど卒業式シーズンなので,卒業記念写真をイメージして)。
出力ファイル
続編
*1:shebang に #!/usr/bin/swift を付けて Swift コードをシェルスクリプト化する方法もありますが,実行環境に Xcode Command Line Tools がインストールされている必要があり,「デフォルト状態で動作する」という要件を満たしません。