memorandums

日々の生活で問題解決したこと、知ってよかったことなどを自分が思い出すために記録しています。

サムネイル画像(html)を生成するrubyプログラム

撮影した写真をサムネイル化してhtml表示するのにIrfanViewを利用してきました。特に理由はないのですが、Windowsをメインで使っていた頃からの習慣で。

ただMacでは利用するたびに仮想化ソフトを起動しなければならず面倒でした。それでも使用頻度が少ないので我慢してきました。

昨夜、少し作ってみたのが以下です。

jqueryなどを利用するとかっこよくサムネイル表示できるのですが、画像数や画像サイズが大きくなると速度的に厳しかった。。。結局、サムネイル画像を作成する必要が生じます。

結局、IrfanViewのサムネイル機能をまねすることにしました。静的ページでイマドキではありませんが、とりあえず利用する分にはいいかな。。。見苦しいソースですが晒します。誰かの役に立つかもしれません。。。

ちなみに下記のプログラムではexifrライブラリを利用しています。未インストールの場合は下記でインストールしてください。

gem install exifr


■使い方
(0)ソース中の(★)を各自の環境にあわせてください。下記のソースは、ユーザ名がhogeで、デスクトップ上のaというフォルダに、画像ファイルが保存されている例です。以下、この例で説明します。

(1) 下記のソースにpics.rbというファイル名をつけ(←ファイル名はなんでもいいのですが)。デスクトップのaにおきます。

(2) 画像ファイルをデスクトップのaフォルダに入れます。

(3)ターミナルで下記のコマンドを実行します。20130412は生成するhtmlファイル名です。省略時はoutになります。

ruby pics.rb 20130421

(4)20130412.htmlというファイルが生成されますのでブラウザなどで開いて確認してください。


■ソース

#↓未インストールの場合は→ gem install exifr
require 'exifr'

#画像ファイルのディレクトリ(★)
IMAGE_DIR = "/Users/hoge/Desktop/a/"

#変換対象画像ファイルの拡張子(★)
EXT = "JPG"

#htmlで表示するときの1行あたりの画像数
COLS = 3

#html背景色
BGCOLOR = "FFFFFF"

#サムネイル画像サイズ
THUMNAIL_SIZE = 200

Dir::chdir("#{IMAGE_DIR}")

#サムネイル画像を生成する
fname = []
Dir::glob("*." + EXT).each {|src|
  dist = src.sub("." + EXT, "_." + EXT)
  fname << [src, dist]

  #縦撮影の画像は回転する
  exif = EXIFR::JPEG.new(src).exif
  degrees = 0
  if exif[:orientation] == EXIFR::TIFF::RightTopOrientation
    degrees = 90
  elsif exif[:orientation] == EXIFR::TIFF::LeftBottomOrientation
    degrees = -90
  end

  `sips -Z #{THUMNAIL_SIZE} #{src} --padToHeightWidth #{THUMNAIL_SIZE} #{THUMNAIL_SIZE} --padColor #{BGCOLOR} --out #{dist}`
  `sips -r #{degrees} #{dist}`
}

#htmlを生成する
cnt = 0
out_fname = (ARGV.size == 0) ? "out" : ARGV[0].to_s
f = open(out_fname + ".html", "w")

f.puts <<"HEADER"
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=shift_jis">
<meta name="GENERATOR" content="IrfanView">
<style>body {font-family:Verdana;}</style>
</head>
<body bgcolor="##{BGCOLOR}">
<center>
<TABLE>
<tr>
HEADER

body = <<"BODY"
<TD ALIGN=CENTER VALIGN=BOTTOM><FONT face="Verdana, Arial, Helvetica, Sans-Serif" size="-2">
<A HREF="BIG" target="_self" style="text-decoration:none"><IMG SRC="SMALL" WIDTH="#{THUMNAIL_SIZE}" HEIGHT="#{THUMNAIL_SIZE}" BORDER="0" ALT="BIG"></A></FONT></TD>
BODY

fname.each {|e|
  f.puts body.gsub("BIG", e[0]).gsub("SMALL", e[1])
  cnt += 1
  if cnt == COLS then cnt = 0; f.puts "</tr><tr>" end
}

f.puts <<"FOOTER"
</tr>
</TABLE>
</center>
</body>
</html>
FOOTER

■あとがき(メモ)
いや。。。想像以上に時間がかかりました。3時間くらいでしょうか。sipsコマンドで縮小画像を生成できることがわかりました。ネットに情報がありましたのですぐ変換できました。しかし縦撮影した画像がMacのプレビューでは問題なく表示されるのにhtml表示すると横になります。。。ここからが大変でした。
exifに入っている撮影方向を取り出して画像を回転してやらなければならなかったんですね。。。プレビューはそれを自動的に処理してくれているわけで。
exifrライブラリをインストールして、使い方を調べつつ方向取得は短時間でできました。が、sipsコマンドへの反映の仕方が悪かった。。。
縮小と同時に回転もできると思いオプションを連続で指定して回転せず。。。回転だけ指定してコマンドラインで実行すると問題ない。ということでsipsコマンドを2回にわけて実行することでうまくいきました。。。
日曜の朝から何をやっているんだか。。。いろいろ勉強になりました。