一括で複数の画像ファイルを余白つけて正方形にする

[最終更新] 2018年1月15日

複数のサイズがまちまちな画像ファイルについて、一括でまとめて正方形にしたい。一辺の長さは縦幅と横幅のうち大きい方を採用し、足りない分は白または透明で塗りつぶす。

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 {} \;

以上。

参考

参考にさせていただきました。ありがとうございます。

関連コンテンツ

関連記事

スポンサーリンク

コメントを残す

メールアドレスが公開されることはありません。