SimpleAPI の仕組みについて考察してみる
最近気になっているサービスと言えば、一躍有名になった「SimpleAPI その1.ウェブサイトサムネイル作成API β版」っていうサービス。その1って書いてあるくらいだから、作者の方はその2、その3を考案中と思われるわけですが、サイトのサムネイルを生成するってのはいろいろなところで役に立ちそうな気がします。
で、できれば自社で同じような仕組みを作って自社で解決したいと思われている方も多くいるのでは?と思います。僕的には会社の仕事からすれば何ら関連のないジャンルのサービスですが、個人的には非常に興味がそそられるサービスなので、その仕組みについて考察してみました。勝手な考察なので、全然違う可能性もあるので、あしからず・・・。
どうやってサイトのサムネイルを生成しているのか?
自前で位置からブラウザの描画を模倣するプログラムってのは作るには敷居が高すぎると直感。特に CSS や JavaScript の挙動を模倣するのはかなりシンドイはず。とすれば、内部的にはブラウザを動かしているはず。サーバは恐らく Linux と思われるので、 mizilla や FireFox や Opera を動かしていると思われます。とすると、ブラウザを起動する環境が必要なはず。X を起動して処理をしているはずがない。とするならば、
1.Xvfb - 仮想フレームバッファってのを使って X の仮想環境をつくって、そこでブラウザを起動する。
これで、仮想フレームバッファ内でブラウザを動作させて別途指定するURLを描画するってことができるようになるので、それをキャプチャして縮小する機能があればよい。
2.Image::Magick を使って仮想フレームバッファをキャプチャして縮小する
おそらく、キモはこの2点と思われます。後は Perl で実装するなら、Perl::Magick つかって 画像の編集とかしてサムネイル生成して、キャッシュ管理とかちゃんとやる感じかなぁ〜と勝手に想像。1つのサービスとして形成するのは結構骨がおれる仕事と思いますが。
で、試しに実験してみます。
Xvfb - 仮想フレームバッファのインストール
OS によって多少名称が異なりますが、XFree86-Xvfb もしくは、xorg-x11-Xvfb ってパッケージをインストールします。僕の環境は CentOS 4.2 で yum つかってパッケージ管理しているのでこんな感じで。Xvfb がインストール済みならここは読み飛ばしてOK。yum grouplist yum groupinfo "X Window System" yum upgrade xorg-x11-xfs yum upgrade xorg-x11 yum upgrade xorg-x11-devel yum upgrade xorg-x11-libs yum groupupdate "X Window System" yum upgrade xorg-x11-libs yum install xorg-x11-Xvfb yum install firefox
これで、一通りパッケージの依存関係を解消しつつ Xvfb の環境が整うはず。やっぱ、OS インストール時にはフルインストールしておくのが便利かも。ブラウザはとりあえず FireFox を使用。JavaScript 関連とかマトモに表示できるんで。
つぎに、FireFox のプロファイルの設定。
firefox -createprofile webshot mkdir /tmp/webshot/
つぎに、Xvfb を起動する init ファイルの作成。
echo '#!/bin/bash # # chkconfig: - 91 35 # description: Starts and stops XVfb. \ # used to provide virtual frame buffer. # Source function library. . /etc/init.d/functions prog=$"Xvfb" # Xvfb program XVFB=/usr/X11R6/bin/Xvfb start() { echo -n $"Starting $prog: " daemon /usr/X11R6/bin/Xvfb :1 -screen 0 1024x1024x24 & echo } stop() { echo -n $"Shutting down $prog: " killproc Xvfb echo } # See how we were called. case "$1" in start) start ;; stop) stop ;; restart|reload) stop start ;; *) echo $"Usage: $0 {start|stop|restart}" exit 1 esac exit 0 ' > /etc/init.d/xvfb chmod 755 /etc/init.d/xvfb chkconfig xvfb on
これで、仮想フレームバッファとブラウザの環境は整う。ちなみに、起動の仕方は下記の通り。
export DISPLAY=:1.0 firefox -display :1 -width 800 -height 1024 -P "webshot" & firefox -display :1 -remote "openurl(http://www.drk7.jp/)"
これで、仮想 X 上に http://www.drk7.jp/ を表紙しているはず。あ、ちなみに、DISPLAY 環境変数の設定は VNC とか使ってすでに :1 が使用済みなら適当に :2 とかで。
コマンドラインベースでサムネイルを生成するスクリプトの実験
取りあえず、コマンドラインベースで動作するヤツ。なんでコマンドラインベースかは下の方で。#!/usr/bin/perl -w use Image::Magick; $ENV{DISPLAY} = ':1.0'; my $url = $ARGV[0] or die 'need url args..'; my $img_fname = 'sample.png'; my $thumb_fname = 'sample_thumb.png'; `firefox -display :1 -remote "openurl($url)"`; `import -display :1 -window root -silent $img_fname`; $img=Image::Magick->new; $img->Read($img_fname); $img->Crop('768x768+0+90'); $img->Set(quality=>90); $img->Scale( width=>128, height=>128 ); $img->Write($thumb_fname);
適当に test.pl とでも保存する。起動の仕方は以下の通り。適当な URL を引数で渡す。
とかやれば、sample_thumb.png っていうサムネイルが生成できているはず。これを CGI 経由で動作させようとすると、何故か、fork して Firefox を実行する部分で Segmentation fault 。むむむ・・・
あと一歩が実は難しい。。。今日はここまで。 ってか、必要なら SimpleAPI 使えばいっか。良くできてるし。それにしても初めて Xvfb なんてものを知りました。Linux 道、奥が深い。。。
コメントやシェアをお願いします!
おしい
このスクリプトのままだとCGIでもバッチでも動かすことはできません。まず、連続して動かすと前回表示した画面がそのまま残ってしまします。次ぎにブラウザが画像を全て読み込む前にスクリーンダンプの処理に移ってしまう可能性があります。どちらにせよ、考え方はあっていますが、このスクリプト自体は使えないと思います。
名無しさん
もちろんWinサーバーですね。
Dex
Winだと楽みたいですね
新にWebToJpegとかゆーのも出てきてますし。
sugi
存在しないページを取りに行かせると、IEエラーメッセージか表示されたりします。
drk
こーのいけさん>はてブのコメントとかみると、Winをバックグラウンドで使ってそうですね・・・
こーのいけ
アクセスログにはMSIEって名乗って来ているようですけど?