アスペクト比と面積から縦横の大きさを求めるRubyスクリプト

Imagemagick-logo

ImageMagick の montage コマンドを使うと複数の画像をタイル状に並べて、1枚のサムネイル集合写真のような画像を作成することができます。スマートフォンの「カメラロール」のようなものです。

tiled-thumbs

具体的には次のようなコマンドでサムネ画像を生成します。

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

という結果が得られます。


  1. montage コマンドはタイル総数よりも入力画像数が多い場合、複数の画像として出力してくれます。また、足りない場合は余白になります。 

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください