以前から何とかしたいと思っていたウェブページのサムネイル生成がようやくできるようになった。以前にやろうとしたときは資料も少なくて、散々悩んだ挙句に放置してしまったが、最近はこういうサービスを提供しているところも多いようで、情報も豊富になってきた。今回も検索にて情報を収集し、ようやく実現にこぎつけたので、ここに諸々メモしておく。
環境としては「Linux下での構築を目指す」これだけ。これで普通の安いVPSを使って構築できるからだ。ちなみに今回使用したのはCentOS4.2。
実現方法は仮想フレームバッファを使用。普通サーバとして使う場合にはX Windowシステムはインストールされていないし、その必要もない。ただしこの機能を実現するに当たって「ブラウザからURLを開き、その画面キャプチャをとる」必要があるので、X Windowシステムが必須となる。そこでX Windowsシステムを仮想的に動作させ、そこでブラウザ起動、URLオープン、画面キャプチャ、画像保存、後処理という手順を踏むことになる。
構築の実際は以下のとおり(参考:Linuxサーバー環境でのサイトサムネイル化:PHPで実行)。
(1) 必要なソフトウェアをインストールする。
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
yum install ImageMagick
とりあえず上から実行していく。途中省略できそうな感じだが、とりあえず言われるままに。
(2) 仮想フレームバッファを起動する
シェルプロンプトで以下のコマンドを実行する(要は仮想フレームバッファをディスプレイ番号1、スクリーン番号0、横1024px縦768x色24ビットで起動しろ、ということ)。
/usr/X11R6/bin/Xvfb :1 -screen 0 1024x768x24 > /dev/null &
(3) 使用ディスプレイの設定する
上でX Windowシステムを起動できた(はず)。上記のディスプレイ・スクリーン番号を使用する旨宣言する(同じくシェルプロンプトで)。
export DISPLAY=:1.0
(4) Firefoxのプロファイルを作成する(最初だけ)
以下のコマンドでプロファイルを作成しておく(コレを作っておかないと、仮想画面上では「プロファイルを作成しますか」画面でとまったままの状態になっている)。以下は「scriptという名前のプロファイルを作成し、その保存場所は/tmp/以下にしなさい」という意味。
/usr/bin/firefox -createprofile "script /tmp/"
(5) Firefoxを起動する
以下のコマンドでFirefoxを起動する。このコマンドの意味は「ディスプレイ番号1を使って、横1024px縦800px、プロファイルscriptを使ってFirefoxを起動」となる。
/usr/bin/firefox -display :1 -width 1024 -height 800 -P "script" > /dev/null &
ここまでで、(2)(5)ではフォント関係のエラーが出るかもしれないが、とりあえず放置しても大丈夫そう。おそらく何か足らないだけなので、別途インストールすることにする。Firefoxが無事起動しているかどうかは、動作中のプロセスを見れば一目瞭然だろう(「ps x」とかで)。
(6) 特定のURLを開く。
とりあえずYahooを開いてみよう。
/usr/bin/firefox -display :1 -remote "openurl(http://www.yahoo.co.jp)" &
(7) 画面をキャプチャする。
ウェブページを開いたブラウザの画面をキャプチャして、ファイルに保存する。「-window root」というのは多分X windowのルートっていう意味(かなぁ?)。
/usr/bin/import -display :1 -window root /tmp/img.gif
これで画面がキャプチャできるはずだ。
個人的に一番はまったのは(3)の使用するディスプレイを設定するところ。多分、前回はコレが発見できなかっただけなんだろうと思う。
さて、これをPHPで扱うにはどうするのが一番いいのかちょっと検討。出来次第、サービスとして提供する予定。期待せずに待っててください。