ImageMagick コマンドで回転アニメーションgifを作る

Linux,Mac,お役立ち情報,プログラム,レビュー,画像処理gifアニメ,imagemagick,アニメーション,シェルスクリプト,動画

ImageMagickconvert コマンドを使って画像を回転させるアニメーション gif を作成するシェルスクリプトです。今回サンプルとして Wikimedia Commons にある次の画像を使います。

The spiral staircase at the Lighthouse in Mitchell Lane, George Gastin, 2008, CC BY-SA 3.0

イマイチな例

「まあ適当に回転させて、アニメーションにしたらいいんでしょ」と思ったけど、甘かったです。

source="変換したいファイル.jpg"

for i in $(seq 1 10)
do
  deg=$((36 * $i)) # 10 回かけて回すので 36 度ずつ掛けて一周させる
  num=$(printf %03d $deg) # ファイル名のために 0 埋め数字をつくる
  convert -rotate $deg ${source} ${num}.jpg # -rotate で 時計回り, +rotate で反時計回り
done
convert -delay 10 ???.jpg anim.gif # 10 ミリ秒間隔でアニメーション

これで出来上がった動画がこちらです。

なんかコレジャナイ感がすごいですね。荒ぶってます。回転させたことで余白が加えられ、各画像のサイズが違ってしまったことが原因です。

ちゃんと中心を合わせて回転させる

これを防ぐために余白を増やしてサイズをあわせることにします。長方形の画像を任意の角度に回転させるとき、取りうる最大サイズは長方形の対角線の長さになります。したがって画像幅 w と画像高さ h をそれぞれ 2 乗して、平方根をとって最大サイズを出します。

まず画像の幅と高さの取得に identify コマンドを利用し、対角線の長さを bc コマンドを利用して計算します。

ww=$(identify -format "%w" source.jpg)
hh=$(identify -format "%h" source.jpg)
length=$(echo "sqrt(${ww}^2 + ${hh}^2)" | bc)

対角線長さでリサイズするには convert コマンドの -extent オプションを利用します。

convert -rotate $deg -extent ${length}x${length} -gravity center source.jpg source-ex.jpg

ここでは -gravity オプションをつけて画像中心周りに回転させるようにしています。

これを組み合わせて回転させるようにして、できた動画がこちらです。

もともとの写真の真ん中はずれてるけど、いい感じです。

以上を一つのシェルスクリプトとしてまとめると以下のような形になります。

#!/bin/sh

source="./temp.jpg"

ww=$(identify -format "%w" ${source})
hh=$(identify -format "%h" ${source})
length=$(echo "sqrt(${ww}^2 + ${hh}^2)" | bc)

for i in $(seq 1 10)
do
    deg=$((36 * $i)) # 10 回かけて回すので 36 度ずつ掛けて一周させる
    num=$(printf %03d $deg) # ファイル名のために 0 埋め数字をつくる
    convert -rotate $deg -extent ${length}x${length} -gravity center ${source} ${num}.jpg # -rotate で 時計回り, +rotate で反時計回り
done
convert -delay 10 ???.jpg anim.gif # 10 ミリ秒間隔でアニメーション

ワンライナーにするならこんな感じ。

source="./temp.jpg"; ww=$(identify -format "%w" ${source}); hh=$(identify -format "%h" ${source}); length=$(echo "sqrt(${ww}^2 + ${hh}^2)" | bc); for i in $(seq 1 10); do; deg=$((36 * $i)); num=$(printf %03d $deg); convert -rotate $deg -extent ${length}x${length} -gravity center ${source} ${num}.jpg; done; convert -delay 10 ???.jpg anim.gif

画像を処理する話なら

シェルスクリプトなどを使って色々画像処理したりしています。他の記事もご覧ください。