ShellScript + ImageMagick 写真処理を効率化！

ShellScriptとImageMagickコマンドラインを使って写真処理をやってみました。

写真処理って普段photoshopかgimpのようなguiソフトを使うでしょう。しかし、時間によって画像を処理するとか、たくさんの写真に同じ処理をするとか、ウェブアプリから写真を処理するとか、するときは、そのようなソフトなら難しいでしょう。

ImageMagickは写真のリサイズ・回転から複数の写真を合成や効果かけるまで全てをコマンドラインで実現することができます。

この記事では、
1. ImageMagickのインストール
2. ImageMagickのコマンドテスト
3. Bashと合わせて使ってみる
4. よく使うコマンドの紹介
という形で進みます。

#ImageMagickのインストール
- [http://www.imagemagick.org/script/binary-releases.php](http://www.imagemagick.org/script/binary-releases.php)　から使用環境に合わせてパッケージをダウンロードします。
- 私の場合、[Mac OS X Binary](http://www.imagemagick.org/script/binary-releases.php#macosx)をMacPortsでインストールします。Homebreawや直接ダウンロードの方法もありますが、MacPorts使ったら他の依存ファイルも自動的にインストールされるそうです。  
*※　MacPortsがない方は、先に[MacPorts](https://www.macports.org/install.php)をインストールします。*
- ターミナルから `sudo port install ImageMagick` でインストールが始まります。パスワードが聞かれましたらrootアクセスのパスワードを入力します。このインストールはちょっと時間かかりますので完了するまでお待ちください。

#ImageMagickのコマンドテスト
ターミナルから、

```shell-session
$ convert image.jpg -implode 1 image-imploded.jpg
```
を実行したら、image.jpgが処理されてimage-imploded.jpgとして保存します。
![result-01.jpg](https://qiita-image-store.s3.amazonaws.com/0/93564/a5231a57-7ed9-e148-4a7e-19370b0a3eb9.jpeg)

*※　convertコマンド見つからないエラーが出る場合、ターミナルを1回閉じて再開しますとできると思います。*

#Bashと合わせて使ってみる
カメラで撮った写真のサイズが大きくてリサイズしたい時、1枚だったらguiソフトでやりますが、何百枚の写真をリサイズするなら大変でしょう。

```bash:resizejpg.sh
#!/bin/bash

for file in *.jpg; do
    filename=( `echo $file | tr -s '.' ' '` )
    convert $file -resize '300>' ${filename[0]}-tmp.${filename[1]}
    size=`identify -ping -format "%[fx:w]x%[fx:h]" ${filename[0]}-tmp.${filename[1]}`
    mv ${filename[0]}-tmp.${filename[1]} ${filename[0]}-${size}.${filename[1]}
done
```
解析：
- `#!/bin/bash`：これからbashシェルが始まるとシステムに通知。
- `for file in *.jpg; do`：現在のディレクトリ中のjpgファイル全部を呼び、変数fileとしてループで使う。
- ``filename=( `echo $file | tr -s '.' ' '` )``：ファイルの名前と拡張を分けて配列としてfilenameに保存。
- ``convert $file -resize '300>' ${filename[0]}-tmp.${filename[1]}``：もし写真の幅が300より大きい場合300にリサイズし、\*-tmp.jpgの新しいファイル名で保存。
- ``size=`identify -ping -format "%[fx:w]x%[fx:h]" ${filename[0]}-tmp.${filename[1]}` ``：新しく保存した写真のサイズを変数sizeに保存。
- ``mv ${filename[0]}-tmp.${filename[1]} ${filename[0]}-${size}.${filename[1]}``：ファイル名を写真サイズをつける(\*幅x高.jpg)。
- `done`：現在のループ完了。

スクリプトを実行すると写真全部は幅300pxにリサイズして新しいサイズをファイル名の後ろに書いて保存します。

#よく使うコマンドの紹介

##resize
先ほどの例で使ったコマンドです。写真サイズを調整します。
>`convert 入力写真.jpg -resize '幅x高(Geometry)' 出力写真.jpg`

幅x高だけではなく以下形でも使えます。
Geometryと言いますが、resizeだけではなく、scale border crop extent thumbnail ... などにも同様です。

|サイズ|例|説明|
|:--|:--|:--|
|*scale%*|50%|幅高両方を半分にする|
|*scale-x%*x*scale-y%*|30x50%|幅30%高50%にする|
|*width*|300|幅を300pxにする。高は自動的に調整|
|x*heihgt*|x300|高を300pxにする。幅は自動的に調整|
|*width*x*height*|500x300|幅と高の最大値。比率を保つ。|
|*width*x*height*^|500x300^|幅と高の最小値。比率を保つ。|
|*width*x*height*!|500x300!|幅500px高300pxにきっぱりと調整。比率を無視。|
|*width*x*height*>|500x300>|幅500px高300pxより大きい場合だけ調整。|
|*width*x*height*<|500x300<|幅500px高300pxより小さい場合だけ調整。|
|@*area*|@10000|写真の面積。だいたい幅115px高86px(9890px)に調整。|

##scale
写真サイズを調整します。
>`convert 入力写真.jpg -scale '幅x高' 出力写真.jpg`

resizeと同じになりますがより処理スピードが速いそうです。

##rotate
写真を回転します。
>`convert 入力写真.jpg -rotate '度' 出力写真.jpg`

`convert image.jpg -rotate '-90' image-rotate-90.jpg`
![result-scale-01.jpg](https://qiita-image-store.s3.amazonaws.com/0/93564/6dc6869e-ece4-4001-a6df-6c98a4809637.jpeg)

##crop
写真をトリム。
>`convert 入力写真.jpg -crop 'Geometry{offset}' 出力写真.jpg`

`convert image.jpg -crop 400x400+170+50 image-crop.jpg`
![result-crop-01.jpg](https://qiita-image-store.s3.amazonaws.com/0/93564/4fc16790-9448-f03c-ed2c-afb556b7dca9.jpeg)
猫ちゃんの写真の元サイズは667x1000で、offset170x50 からの400x400はちょうどう頭のところになります。

##border
写真ボーダーを作る。
>`convert 入力写真.jpg -bordercolor '(#haxcolor|色)' -border 'Geometry' 出力写真.jpg`

`convert image.jpg -bordercolor SkyBlue -border 50x50 image-border.jpg`
![result-border-01-crop.jpg](https://qiita-image-store.s3.amazonaws.com/0/93564/3cb96d65-d24d-f731-0df1-902a97594a0a.jpeg)

##flip
写真を上下反転。
>`convert 入力写真.jpg -flip 出力写真.jpg`

`convert image.jpg -flip image-flip.jpg`
![result-flip-01-crop.jpg](https://qiita-image-store.s3.amazonaws.com/0/93564/7aeddf38-50f2-b50c-ee29-d24a2bee2184.jpeg)

##flop
写真を左右反転。
>`convert 入力写真.jpg -flop 出力写真.jpg`

`convert image.jpg -flop image-flop.jpg`
![result-flop-01-crop.jpg](https://qiita-image-store.s3.amazonaws.com/0/93564/87ea670f-436e-9be7-e02d-4678eef4cea0.jpeg)

##draw
写真上ものを描きます。なんでも描けるますが、円と長方形描いみましょう。

```
convert image.jpg -fill white -draw 'circle 200,100 120,40' \
-fill blue -draw 'fill-opacity 0.8 rectangle 150,60 250,80' \
image-draw.jpg
```
![result-draw-01-crop.jpg](https://qiita-image-store.s3.amazonaws.com/0/93564/3b284380-cb1e-49d9-562c-50c2700643b8.jpeg)
写真元サイズ：400x400

##append
複数の写真を繋ぐ。この記事で使ってる効果前、効果後の写真は以下のようなコマンドで作りました。

```
convert \( image-before.jpg -resize 400 \) \
\( arrow.png -resize '100' -gravity Center -extent x200 \) \
\( image-after.jpg -resize 400 \) \
+append image-result.jpg
```

**基本のコマンドしか紹介してなかったですが、他の素晴らしい効果のコマンドや使い方を[こちら](http://www.imagemagick.org/script/command-line-options.php)からご参考できます。**

```
convert image.jpg -charcoal 2 image-charcoal.jpg
```
![result-charcoal-01-crop.jpg](https://qiita-image-store.s3.amazonaws.com/0/93564/6f55e600-2108-06f4-c185-ae852ae8757c.jpeg)


猫写真：[PAKUTASO](https://www.pakutaso.com)