PythonとGraphicsMagicでイメージマップを作る。

ウェブ用にサムネ一覧を作ると、個々の画像がHTTPヒットとなりユーザもサーバもストレスを感じる。でも複数の画像をイメージマップとして一つのにまとめれば軽くなる。GraphicsMagicにはmontageというコマンドがあって与えたJPGファイルを表型の一つの画像にしてくれるので、あとはそれに合せてMAPとAREAタグを生成すればいい。以下、pythonのイメージマップコマンド。


# -*- coding: utf-8 -*-
import sys

def kwdict(**kw):
""" kw --> dict """
return kw

# gmAPIとかあるんだろうが、手っ取り早くコマンドで処理する。
def run_cmd(cmd):
""" コマンド走らせて、エラーがあったら返す """
import subprocess
cmd=subprocess.Popen(cmd.split(' '), stderr=subprocess.PIPE)
err=cmd.stderr.read()
cmd.wait()
return err

def montage_cmd(**opt):
""" GraphicsMagichのmontageコマンド """
opt['img_files_as_string']=' '.join(opt['img_files']) # xx
return ' '.join(['/usr/bin/gm montage',
'-geometry %(width)dx%(height)d',
'-tile %(num_cols)dx%(num_rows)d',
'%(img_files_as_string)s %(montage_file)s']) % opt

def coord_g(width,height,num_cols):
""" 呼ばれる度に指定されたレイアイトパラメタに基いてareaタグのcoordに適切な座標を返すジェネレータ。"""
(x,y)=(0,0)
while(True):
for x in [i*width for i in range(num_cols)]:
yield(x,y)
y+=height

def area_g(img_files, width, height, num_cols, **opt):
""" areaタグを生成する。このジェネレータたと上のがlock-stepで呼出されることによって
ツジツマの合ったイメージマップが生成される(んだと思う)。
"""
xy=coord_g(width, height, num_cols)
for img in img_files:
(x,y)=xy.next()
yield '<area shape="rect" coords="%(coord)s" href="%(img)s" />' \
% kwdict(img=img,
coord=','.join(map(str,[x,y,x+width,y+height])))


def map_html_template():
return """
<img src="%(montage_url)s" usemap="#montage">
<map name="montage">
%(areas)s
</map>
"""

if __name__=='__main__':
opt=kwdict(
width=150, # セルの幅(ピクセル)
height=150, # 高さ
num_cols=5, # 横にいくつ並べるか
num_rows=20, # roundup(len(img_files)/num_cols)にすべき。
montage_file='xx.jpg', # 生成されるjpgファイル
montage_url='xx.jpg', # HTMLと同じディレクトリに吐くばあいこの相対URLでOK
# 標準入力から画像パスを読み込む
img_files=[l.strip('\n') for l in sys.stdin.readlines()],
)
# モンタージュ画像を生成
err=run_cmd(montage_cmd(**opt))
if err: raise RuntimeError(err + ': ' + cmd)
# 標準出力にHTMLを掃き出す。
print map_html_template() % {'montage_url':opt['montage_url'],
'areas':"\n".join(list(area_g(**opt)))}

使い方


find ~/Desktop/ -name '*.JPG' \
| head -10 \
| python montage.py \
> montage.html
firefox -a firefox -remote "openurl(file://`pwd`/montage.html)"

こんな感じにできあがる。

サムネにクリックするとオリジナルのサイズに飛ぶ。javascriptつかえば、mouseoverで拡大なんてこともできるね。