sipsはサブディレクトリを再帰的に処理しないため、ディレクトリ以下の画像をまとめて処理したい場合はfindと組み合わせる。

参考: 【sips】コマンドで画像をリサイズする

findとsipsを組み合わせて一括リサイズする

find <ディレクトリ> -name <パターン> -exec sips ... {} \;で、サブディレクトリ以下の画像もまとめて処理できる。{}が見つかったファイルパスに置き換わる。--outを省略すると元のファイルに上書きされる。

$ find imgs -name "*.png" -exec sips -Z 400 {} \;
$ find imgs -name "*.png" -exec sips -g pixelWidth -g pixelHeight {} \;
imgs/b.png
  pixelWidth: 400
  pixelHeight: 210
imgs/a.png
  pixelWidth: 400
  pixelHeight: 210
imgs/sub/c.png
  pixelWidth: 400
  pixelHeight: 210

–outにディレクトリを指定するとサブディレクトリ構造が失われる

--outに出力先ディレクトリを指定してフォーマット変換する場合、サブディレクトリの階層構造は保たれず、すべて同じディレクトリに書き出される。

$ find imgs -name "*.png" -exec sips -s format jpeg {} --out out/ \;
$ ls out/
a.jpg
b.jpg
c.jpg

imgs/sub/c.pngimgs/sub2/c.pngのように、異なるディレクトリに同名のファイルが存在する場合、どちらもout/c.jpgという同じパスに書き出されるため、後から処理された方が先に書き出されたファイルを上書きする。件数が減っていないか、処理前後でファイル数を確認した方がよい。

xargsで並列処理する場合の注意

xargs -Pを使うと複数のsipsプロセスを並列実行でき、大量の画像を処理する際の時間短縮になる。

$ find imgs -name "*.png" -print0 | xargs -0 -P 4 -I{} sips -s format jpeg {} --out out/

ただし、前述のように出力先ファイル名が衝突する場合、並列実行時は単なる上書きではなく書き込みエラーになることがある。

Error: Cannot to rename temporary file to /path/to/out/c.jpg
Error 13: an unknown error occurred

sipsは書き込み時に一時ファイルを作成してからリネームするため、複数プロセスが同じ出力ファイル名に同時に書き込もうとするとリネームに失敗する。並列実行する場合は、出力ファイル名が衝突しないことを事前に確認しておく。

参考

SIPS Command: Scriptable Image Processing System in macOS