シェルスクリプトでまとめて画像を軽量化して保存する

edit-images-using-shellscript

前回の記事でコマンドを使った画像データ処理を行いました。

これを少し発展させてコマンドによる画像処理をシェルスクリプトで実行できるようにしました。この記事では作成したスクリプトについて解説しています。

行いたい処理と作業の前提

「複数のディレクトリの配下にある複数の画像を軽量化してから任意のディレクトリに保存する」処理の例です。

  • 画像形式はすべてPNGである。
  • デスクトップにある処理対象のディレクトリ名に接頭辞をつけている。
  • 軽量化後の画像の移動先となるディレクトリがある。
# 以下のように~/Desktopに保存されているとします。
hoge_dirA
∟img1.png
∟img2.png
∟img3.png
hoge_dirB
∟img4.png
∟img5.png
∟img6.png
hoge_dirC
∟img7.png
∟img8.png
∟img9.png

作成したシェルスクリプト


ファイル名の末尾にある.shは分かりやすさのためにつけるもので動作に必須ではありません。

#!bin/bash
cd ~/Desktop
DIRS=<code>find ~/Desktop/ -type d -name "hoge_*"</code>
for DIR in $DIRS;
do
 basename $DIR
 cd $DIR
 BEFORE=<code>du -s -h</code>
 sips --resampleWidth 1440 *.png
 sips -s dpiHeight 72 -s dpiWidth 72 *.png
 ls | xargs -I{} basename {} .png | xargs -I{} sips -s format jpeg -s formatOptions 50 {}.png --out {}.jpeg
 rm *.png
 AFTER=<code>du -s -h</code>
 echo "軽量化前: ${BEFORE}"
 echo "軽量化後: ${AFTER}"
done
cd [保存先ディレクトリまでのパス]
pwd
mv ~/Desktop/hoge_* .
ls -1
exit 0

解説

確認しておきたい部分について軽く解説します。

シェバン(shebang)

#!bin/bash

1行目に書くとシェルスクリプト として解釈されるファイルになります。シェルは人間のユーザーとOSを仲介しているプログラムであり、シェルに入力するコマンドを並べたものがシェルスクリプトです。bashはよく使われているシェルの一種である。他にはzshやshなどがあります。シェバンでは書かれたスクリプトを読み込むもの(インタプリタ)が何なのかを指定しています。

配列

DIRS=`find ~/Desktop/ -type d -name "hoge_*"`

findでデスクトップにある(~/Desktop)ディレクトリで(-type d)名前の先頭が「hoge_」に一致する(-name “hoge_*” )ものを取得して、変数DIRSに格納します。「=」の前後に半角スペースを入れたくなりますが、なしにしないとエラーになります。

#変数の中身を出力すると?
echo $DIRS
#以下のようになる
/Users/username/Desktop//hoge_C /Users/username/Desktop//hoge_B /Users/username/Desktop//hoge_A

繰り返し処理

for DIR in $DIRS;
do
#処理内容
done

シェルスクリプトでは制御構文もかけます。$DIRSに格納された各ディレクトリを変数DIRに格納してdoとdoneの間に記述した処理を実行します。cd $DIRで移動しないと各ディレクトリの中身に対する処理ができませんでした。

basename コマンド

basename $DIR

basename [パス名]
引数に指定したパス名からファイル名またはディレクトリ名の部分を返します。最後のスラッシュ以前の文字が切り取られます。

basename [パス名] [接尾辞]
接尾辞も取り除いた文字列が返されます。

xargsコマンド

ls | xargs -I{} basename {} .png | xargs -I{} sips -s format jpeg -s formatOptions 50 {}.png --out {}.jpeg

PNG形式からJPEG形式に変換する部分です。やや込み入って見えます。
xargsは前のコマンドの実行結果を受け取って引数のリストを作成し、次のコマンドに渡して実行します。{}の部分に引数として文字列が入ります。
lsの結果がxargsに渡され、xargsはそれを1つずつbasenameコマンドの引数として渡して実行します。接尾辞の「.png」が取り除かれ、パス名と拡張子を除いたファイル名だけが抽出されます。
さらに、抽出したファイル名をxargsに送りこんでsipsコマンドの引数にして実行します。{}の部分がファイル名で置き換えられます。
結果としては、拡張子だけが異なるファイルを書き出すことができるようになっています。

変数の値を文字列として出力する

echo "軽量化前: ${BEFORE}"

シェルスクリプトで文字列内に変数を埋める時は${ }の中に変数名をいれます。

実行する

実行はスクリプトファイルの絶対パスを入力するとできますが、パスを通しておくと楽に実行できます。シェルスクリプトを保存するディレクトリshellscriptを作成し、.bash_profileに、export PATH=”~/shellscript/:$PATH”を追記しました。これで以下のコマンドを入力すると実行されました。

bash edit_img.sh

シェルスクリプトについて今後やること

  • シェルスクリプトが活用できる場面ではどんどん使っていく。
  • 実務的にはどんな場面で具体的に使われるか調べてみる。