Automatorで右クリックから動画をアニメーションGIFにしたり、画像を横や縦に結合する
プルリクエストやSlackなどでキャプチャーや動画を添付しておくと、相談や共有がしやすくなります。
でも、動画だとファイルサイズが大きすぎたり、複数の画像を1枚にまとめたいときってないですか?
アプリを探して使うのもいいのですが、足りない機能があったり、その都度設定をしないといけない手間があったります。そこで便利なのが、FFmpegやImageMagickなどのライブラリをAutomatorで使えるようにすることです。
AutomatorはMacの標準アプリで、ワークフローを自動化して作業を効率化できます。
Mac用Automatorユーザガイド - Apple サポート (日本)
ライブラリをインストールする
使用しているライブラリは「FFmpeg」と「ImageMagick」です。
A complete, cross-platform solution to record, convert and stream audio and video.
オーディオとビデオを録音、変換、ストリーミングするための完全なクロスプラットフォームソリューションです。
ImageMagick® is a free, open-source software suite, used for editing and manipulating digital images. It can be used to create, edit, compose, or convert bitmap images, and supports a wide range of file formats, including JPEG, PNG, GIF, TIFF, and Ultra HDR.
ImageMagick®は、デジタル画像の編集や操作に使用される、フリーでオープンソースのソフトウェアスイートです。ビットマップ画像の作成、編集、合成、変換に使用でき、JPEG、PNG、GIF、TIFF、Ultra HDRなど幅広いファイル形式をサポートしています。
Homebrewでは次のコマンドでインストールできます。
brew install ffmpeg
brew install imagemagick
お好みのライブラリに変更してもらっても大丈夫です。
動画をGIFに変換する
まずAutomatorを開きます(標準で搭載されています)。
Command + Nで新規ファイルを作成、「クイックアクション」をクリックしてから「選択」してください。
次のように設定します。
- 「アクション」にある「ユーティリティ」から「シェルスクリプトを実行」をグレーのエリアにドラッグする
- 「ワークフローが受け取る現在の項目」を「ムービーファイル」にする
- 「検索対象」を「Finder」にする
シェルスクリプトは次のように設定します。
- 「シェル」は使っているシェルにする(M1以降は基本的にzsh)
- 「入力の引き渡し方法」は「引数として」にする
-
for f in "$@"
の部分は次のように上書きする
# 引数`$1`からディレクトリパスを取得、`dirname`で絶対パスからディレクトリ部分を抽出する
dir=$(dirname "$1")
cd $dir
# FPSを10、横幅は640px、高さはアスペクト比を保って出力する
/opt/homebrew/bin/ffmpeg -i "$1" -vf "fps=10,scale=640:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -r 10 "$1.gif"
処理内容は[Mac]右クリックメニューから動画をアニメーションGIFに変換する #ffmpeg - Qiitaを参考にさせていただきました。
ファイル名は「元のファイル名.mov.gif」のように、同じディレクトリに出力されます。
次のような設定を用途に合わせて調整してください。
-
fps=10
:スクリーンショットのデフォルトFPSは60でした -
scale=640:-1
:横幅は640pxで高さはアスペクト比を維持しています(逆にしたい場合はscale=-1:640
)
その他の設定は最適化する処理らしく、関連する記事がいくつかあったので詳しくはググってみてください。
Command + Sをしてファイル名を設定して保存したら完成です。
Command + Shift + 5から「選択部分を収録」を選択してキャプチャーを録画しておきます。
そのファイルを右クリックして「クイックアクション」から「動画をGIFに変換する」と名前をつけたアクションを実行すると、アニメーションGIFが動画ファイルと同じフォルダに出力されます。
参考までに前後のファイル情報です(再生時間は4秒)。
- 変換前
- 解像度:2114×1476
- データ容量:4.7MB
- 変換後
- 解像度:640×447
- データ容量:311KB
元の解像度にもよりますが、少なくとも50%くらいには最適化できています。
変換したアニメーションGIFです。元動画より荒くはなってしまいますが、画面の共有としては十分だと思います。
画像を結合する
GIFへの変換と同じ要領で、画像の結合(複数の画像を1つのファイルにする)も作成します。
結合する方向によってオプションが変わるので、アクションも横と縦の2つを登録しています。
アクションの登録時に結合する方向を選択させることもできそうですが、一手間増えてしまうので、それぞれに用意しておくほうが使い勝手がよさそうです。
「ワークフローが受け取る現在の項目」を「画像ファイル」にしておいてください。それ以外はGIFに変換した設定と同じです。
画像を横に結合するシェルスクリプト。
# 引数`$1`からディレクトリパスを取得、`dirname`で絶対パスからディレクトリ部分を抽出する
dir=$(dirname "$1")
cd $dir
# 出力ファイル名(例:`output_2024年09月14日_22時27分50秒.png`)
output_file="output_$(date +'%Y年%m月%d日_%H時%M分%S秒').png"
# `$@`に入っている選択した画像の絶対パスをループ、image_filesに半角スペース区切りで絶対パスを格納する
image_files=""
for file in "$@"; do
image_files="$image_files \"$file\""
done
# magickコマンドを実行して画像を横方向に結合する
eval /opt/homebrew/bin/magick $image_files +append "$output_file"
画像を縦に結合するシェルスクリプト。
# 引数`$1`からディレクトリパスを取得、`dirname`で絶対パスからディレクトリ部分を抽出する
dir=$(dirname "$1")
cd $dir
# 出力ファイル名(例:`output_2024年09月14日_22時27分50秒.png`)
output_file="output_$(date +'%Y年%m月%d日_%H時%M分%S秒').png"
# `$@`に入っている選択した画像の絶対パスをループ、image_filesに半角スペース区切りで絶対パスを格納する
image_files=""
for file in "$@"; do
image_files="$image_files \"$file\""
done
# magickコマンドを実行して画像を縦に結合する
eval /opt/homebrew/bin/magick $image_files -append "$output_file"
出力するファイル名はoutput_2024年09月14日_22時27分50秒.png
のようにしています。こちらもワークフローにファイル名の設定を追加しようとも思ったのですが、出力後に必要に応じてファイル名を変更するほうが汎用性が高いかなと思っています。
以上です。
シェルスクリプトを書いたことはなかったのですが、AIにベースを書いてもらえるのでありたいですね。とはいえ、正常に動作しないコードになることも多いので、機能を追加していく場合は参考情報を渡したり、自分でシェルの書き方を覚えておく必要も出てきそうです。
FFmpegとImageMagickも色々なオプションがありますし、Automatorにも色々なアクションがあったりフォルダに対してアクションを設定できたりします。
もし今回紹介した方法以外にも便利なアクションがあったらぜひコメントで教えてください!
ちょっと株式会社(chot-inc.com)のエンジニアブログです。 フロントエンドエンジニア募集中! カジュアル面接申し込みはこちらから chot-inc.com/recruit/iuj62owig
Discussion