複数のサイズがまちまちな画像ファイルについて、一括でまとめて正方形にしたい。一辺の長さは縦幅と横幅のうち大きい方を採用し、足りない分は白または透明で塗りつぶす。
imagemagickを使ってシェルスクリプトで実装した。
ソースコード
環境はmacOS 10.13でGNU bash 3.2.57。
まず、余白をつけるのは以下のコマンド。
convert hoge.jpg -background none -gravity center -extent 300x300 hoge-out.jpg
背景色を白に指定する場合は、-background noneでwhiteを指定。-gravityは開始位置で、指定しない場合は左上がデフォルト。
これを使って、複数ファイルについて適用するシェルスクリプトを以下に書く。余白は白色。画像以外のファイルを入力した場合はスルー。出力先はsquareディレクトリを作成して、その中に元ファイル名-square.jpgというようにする。入力ファイルがサブディレクトリ内のファイルであった場合は、階層構造を保持するようにして出力する。たとえば、img/hoge1.jpg を入力にしたら、出力先はsquare/img/hoge1-square.jpg となる。
#!/bin/bash
set -eu
if [ ${#} -eq 0 ]; then exit 0 ;fi
for i in $(seq ${#})
do
# echo "${1}"
# 画像以外は弾く
set +e
identify "${1}" > /dev/null 2>&1
if [ $? -ne 0 ]; then
shift
continue
fi
set -e
# 縦幅と横幅を抽出
width=$(identify -format "%w" "${1}")
height=$(identify -format "%h" "${1}")
# 大きい方を一辺にする
if [ "${width}" -ge "${height}" ]; then
side="${width}"
else
side="${height}"
fi
# 出力先
# 拡張子抜き出し
ext=${1##*.}
bname=$(basename "${1}")
dname=sqaure/$(dirname "${1}")
if [ ! -e "${dname}" ]; then mkdir -p "${dname}"; fi
sqimg="${dname}/${bname%.*}-square.${ext}"
# 変換
convert "${1}" -background white -gravity center -extent "${side}x${side}" "${sqimg}"
shift
done
$#は引数の個数。identifyでエラーが返ったら画像ではないと判定する。ext=${1##*.}は、パターンマッチングで前方削除による拡張子の抜き出し。
サイズも調整するなら、以下を付け足して出力ファイルについてさらに変換するとか。
mogrify -thumbnail 150x150 "${sqimg}"
いっぺんにやることもできるんだろうか。まぁでも分けたほうがメンテナンス性も良い気がする。
使い方
以上のコードを、たとえばsq.shとしたら、
./sq.sh *
とすると、カレントディレクトリにある画像ファイルについて処理を行う。
応用で、たとえばhogeディレクトリ以下にあるサブディレクトリ内含めたすべての画像ファイルについて適用したい場合は、以下のようにすると良い。
find hoge -name "*.*" -exec ./sq.sh {} \;
以上。
参考
参考にさせていただきました。ありがとうございます。
- bashの変数展開によるファイル名や拡張子の取得 - Qiita
- [ImageMagick] 画像の大きさ(幅と高さのピクセル数)を取得するコマンド · DQNEO起業日記
- 引数を処理する | UNIX & Linux コマンド・シェルスクリプト リファレンス
- 【shiftコマンド】bashで引数の数が可変の場合の処理 - 養殖Geekは川を上るか
- 画像のサイズ変更(切り抜き・塗足し etc.) – Imagemagickの使い方日本語マニュアル
- 【ImageMagick】画像の縮小(サムネイル作成)とExif情報削除 at softelメモ
- 画像の拡大・縮小 – Imagemagickの使い方日本語マニュアル
コメント