ImageMagick の montage コマンドを使うと複数の画像をタイル状に並べて、1枚のサムネイル集合写真のような画像を作成することができます。スマートフォンの「カメラロール」のようなものです。
具体的には次のようなコマンドでサムネ画像を生成します。
montage -background black -tile 11x20 -geometry 48x48+0+0 *.jpg thumb.jpg
ここで問題となるのが -tile
オプション。これは、「複数の入力画像を縦横何個ずつ並べるか」を指定するオプションです。入力画像ファイル数が少なかったり、出力画像のアスペクト比が 1:1 であれば単純に入力画像ファイル数の冪根を求めればいいだけなのですが、16:9 などといったスマホの画面で閲覧させるのを前提としたアスペクト比の場合、何個ずつ並べればいいかの計算がちょっと厄介になります。
入力画像が正方形の場合、入力総数を [math]n[/math], 求めたい縦横何個を [math]x, y[/math], 縦横比を [math]w, h[/math], アスペクト比を升目と考えた時の総数に対する比を [math]t[/math] とおくと、[math]n = xy[/math] で [math]xy \leq wt \cdot ht[/math] を満せばいいわけなので、[math]x, y[/math] それぞれについて解くと、
[math]x = w \sqrt{\mathstrut \frac{n}{wh} }, y = h \sqrt{\mathstrut \frac{n}{wh} }[/math]
という具合になります。
これを Ruby に書き直して計算結果を印字するようにしたものが次のコードです。
#!/usr/bin/env ruby
# 総数
n = 333
# 比率
w = 16
h = 9
def calc(n, w, h)
t = Math.sqrt(n.to_f / (w * h).to_f)
return (w * t).to_i, (h * t).to_i
end
x, y = calc(n, w, h)
if x * y < n
x, y = calc(n + x, w, h)
end
puts "#{x}x#{y}"
calc
の戻り値は個数を表すため必ず整数値になるわけですが、総数よりも小さい場合は1枚の画像に収まらないため1、再計算させています。 上の例のように、333 ファイルを 16:9 の比でタイル配置したい場合
25x14
という結果が得られます。
-
montage コマンドはタイル総数よりも入力画像数が多い場合、複数の画像として出力してくれます。また、足りない場合は余白になります。 ↩