2019-06-19

ImageMagick で 16:9 トリミングを自動化

皆さんは画像を SNS や自身のブログなどに投稿する際に加工したことはないでしょうか? Twitter では画像が自動的に 16:9 で表示されるため、予め 16:9 でトリミングしておくことでどのように表示されるかを調整できます。 トリミング機能は Android 版にはありますが Web 版にはないため、PC からの画像投稿のときに少し面倒に感じたりします。

    画像編集の自動化といえば ImageMagick

    そこで GIMP などの画像編集ソフトが必要になりますが、私は ImageMagick を利用しています。 画像の加工を自動で行うためのコマンドラインが用意されており、例えば以下のようにすれば png ファイルを一括で余白トリミングできます。 GIMP でいう「最小枠で切り抜き」機能ですね。

    $ mogrify -trim *.png
    

    画像サイズを指定しての切り抜きは ImageMagick の crop オプションを使います。 座標 (X, Y) の位置で幅 W px、高さ H px のトリミングをするには以下のコマンドを打ちます。

    $ convert (元ファイル) -crop WxH+X+Y (出力パス)
    

    しかし、残念ながら比率 (16:9 など) の指定によるトリミングには対応していません。 そこで、比率指定によるトリミングのコマンドをシェルスクリプトで作りました。

    trimrate コマンドを作ってみた

    結論から言うと、比率指定によるトリミングコマンドを以下のように作りました。

    このシェルスクリプトを trimrate というファイル名で保存します。 保存先は /usr/local/bin などのパスが通ってるところが便利です。 そして chmod +x trimrate で実行権限を与えて以下の構文でトリミングを行います。

    $ trimrate (元ファイル) (幅比率) (高さ比率) (X オフセット) (Y オフセット) (出力パス) [(ImageMagick オプション)]
    $ trimrate src.jpg 16 9 0 0 dest.jpg -gravity center (←こんな感じ)
    

    コマンドの動作的には、比率から切り抜きの幅高さを計算して ImageMagick の crop 機能を呼び出しているだけです。 デフォルトだと画像の上部でトリミングするため、-gravity center オプションを加えて中央でトリミングしています。

    for 文で一括処理する

    trimrate コマンドだけだと mogrify のように複数のファイルを一括処理することができません。 しかし、bashfor 文で画像ファイルごとに trimrate を実行して一括処理させることはできます。

    $ mkdir 16-9
    $ for file in `ls *.jpg`; do trimrate ${file} 16 9 0 0 16-9/${file} -gravity center; done
    

    やってることは、16-9 という名前でディレクトリを作り、ls *.jpgfor 文で jpg ファイルのループ処理をしています。 identify コマンドでトリミング前後の画像ファイルを確認すると、

    $ identify *.jpg  (トリミング前)
    publicdomainq-0029161ayicpk.jpg JPEG 3491x2410 3491x2410+0+0 8-bit sRGB 1.476MB 0.030u 0:00.020
    publicdomainq-0029407uhs.jpg JPEG 900x675 900x675+0+0 8-bit sRGB 111KB 0.010u 0:00.009
    publicdomainq-0031792moqgua.jpg JPEG 5184x3456 5184x3456+0+0 8-bit sRGB 3.616MB 0.000u 0:00.000
    publicdomainq-0031794ftclzr.jpg JPEG 5184x3456 5184x3456+0+0 8-bit sRGB 5.388MB 0.280u 0:00.289
    publicdomainq-0031795pgepte.jpg JPEG 5472x3648 5472x3648+0+0 8-bit sRGB 5.073MB 0.000u 0:00.000
    publicdomainq-0033354fvanhv.jpg JPEG 4752x3168 4752x3168+0+0 8-bit sRGB 5.697MB 0.280u 0:00.269
    $ identify 16-9/*.jpg  (トリミング後)
    16-9/publicdomainq-0029161ayicpk.jpg JPEG 3491x1963 3491x1963+0+0 8-bit sRGB 1.462MB 0.010u 0:00.019
    16-9/publicdomainq-0029407uhs.jpg JPEG 900x506 900x506+0+0 8-bit sRGB 112KB 0.000u 0:00.000
    16-9/publicdomainq-0031792moqgua.jpg JPEG 5184x2916 5184x2916+0+0 8-bit sRGB 3.468MB 0.000u 0:00.000
    16-9/publicdomainq-0031794ftclzr.jpg JPEG 5184x2916 5184x2916+0+0 8-bit sRGB 5.783MB 0.000u 0:00.000
    16-9/publicdomainq-0031795pgepte.jpg JPEG 5472x3078 5472x3078+0+0 8-bit sRGB 5.342MB 0.000u 0:00.000
    16-9/publicdomainq-0033354fvanhv.jpg JPEG 4752x2673 4752x2673+0+0 8-bit sRGB 5.354MB 0.010u 0:00.000
    

    このとおり 16:9 になっています。 display コマンドで中身を確認すると、ちゃんと中央でのトリミングになっていました。

    トリミング前 トリミング前

    トリミング後 トリミング後

    作業効率化で差をつけよう

    デスクワークでは画像の編集もよくあることだと思いますが、コマンドによる作業効率化はあまり知られていないように感じます。 ドキュメントであれば文字の置換など作業効率化のイメージがつきますが、画像になると人手でやるしかない、と思われる方も多いと思います。 (私の前職ではまさかのペイントしか使えない環境だったので……) ぜひ、画像においても作業効率化が普及することを願います。

    この記事の執筆者

    hato6502

    hata  

    中学生の頃に 6502 という CPU からプログラミングの世界に入りました。 C/C++ で1から作ることも好きですが、最近は変化の激しい IT 業界をみて Web 系にシフトしつつあります。