やまものブログ

メモ書きブログです (^_^;A

JPEGを縦横半分に縮小するワンライナー(convert 利用)

カレントに jpeg 拡張子の JPEG ファイルがあるとします。

下記のコマンドで、
 ・サブディレクトリ shrink/ を作成して、
 ・そこに縦横半分(面積1/4)に縮小したJPEGを生成
しました。

$ mkdir shrink
$ for f in *.jpeg ; do file $f | gawk '{print $1,gensub(",","",1,$(NF-2))}'| perl -ne 'if(/([\w\.]+): (\d+)x(\d+)/){$w=int $2/2;$h=int $3/2; $c="convert -resize ${h}x${w} $1 shrink/$1"; system($c)}' ; done


JPEGファイルを file コマンドにかけると以下の情報が得られます。
<ファイル名>: JPEG image data, … 中略 …, 2286x1614, frames 3
終わりから3カラム目が「横幅x高さ」の情報です。


サイズの変換は、convert でこんな風に実行できました。
$ convert -resize <横幅x高さ> <入力ファイル> <出力ファイル>

これらを利用すると、
 ・file コマンドで「横幅x高さ」を得て、
 ・それらを2で割って、
 ・convert に食わせる
ことができれば目的を達成できます。

これを実行している2行目のワンライナーを分解するとこんな感じです。

for f in *.jpeg ; do
    → bashのforループ
file $f
    → file コマンドにかける
| gawk '{print $1,gensub(",","",1,$(NF-2))}'
    → 「ファイル名」「横幅x高さ」を取り出す。
| perl -ne 'if(/([\w\.]+): (\d+)x(\d+)/){
    → perl の文字列検索
$w=int $2/2;
    → 後方参照で「横幅」をとって2で割って整数部分をとる
$h=int $3/2;
    → 「高さ」について同上
$c="convert -resize ${h}x${w} $1 shrink/$1";
    → convertコマンドを組み立てる
system($c)
    → system() で実行
}'
; done

また、後で使いそうなのでメモしました


● file コマンドで画像ファイルの情報を取れない場合あり (2018/08/12(日)追記)
  identify コマンドで問題を回避できたので、以下のように修正

for f in *.jpeg ; do identify $f | gawk '{print $1,$3}'| perl -ne 'if(/([\w\.]+) (\d+)x(\d+)/){$w=int $2/2;$h=int $3/2; $c="convert -resize ${h}x${w} $1 shrink/$1"; system($c)}' ; done

こっちの方が簡単です