akishin999の日記

調べた事などを書いて行きます。

mod_small_light で動的に画像リサイズ

今更ですが、livedoor により提供されている mod_small_light をインストールしてみました。
mod_small_light は動的にサムネイル画像を生成したりできる Apache モジュールです。

SMALL LIGHT 〜かんたん画像サムネイル作成モジュール〜 | livedoor labs EDGE
http://labs.edge.jp/smalllight/

ちなみに、mod_small_light は OpenMP が有効な ImageMagick ではビルド時にエラーになってしまうようなので、前回インストールした OpenMP を無効にしたものを使用しています。

==================== 2013/06/15 追記 ====================
コメント欄で id:cubicdaiya さんに教えて頂きました。

以下にあるパッチを Makefile.in に当てる事で、OpenMP が有効な ImageMagick でも mod_small_light のビルドが通るようになります。

https://github.com/yamac/smalllight/pull/2/files

また、ImageMagickOpenMP が有効なままだとサーバが高負荷になる問題がありますが、そちらは環境変数「OMP_NUM_THREADS」に 1 を設定する事で回避できます。

配布されている ImageMagick ではデフォルトで OpenMP が有効なので、Bugfix などで小まめにアップデートすることを考えると提供されている RPM をそのまま入れて、OpenMP環境変数で制御する、という運用の方が良さそうです。

id:cubicdaiya さん、ありがとうございました!

==================== 追記ここまで ====================

検証環境は以下になります。

インストール

Apache モジュールなので、まずは httpd-devel をインストールします。

# yum install httpd-devel

標準リポジトリなので、Apache/2.2.15 がインストールされました。

# apachectl -v
Server version: Apache/2.2.15 (Unix)
Server built:   May 13 2013 22:11:16

imlib2 は EPEL にあるものを使用します。

# yum install http://dl.fedoraproject.org/pub/epel/6/x86_64/imlib2-1.4.2-5.el6.x86_64.rpm \
              http://dl.fedoraproject.org/pub/epel/6/x86_64/imlib2-devel-1.4.2-5.el6.x86_64.rpm

ImageMagick前回入れたものをそのまま使用します。
これで必要なモジュールはインストール出来たので、いよいよ mod_small_light をインストールします。

ソースコードから入れるので make install は Paco 経由で。

# cd /usr/local/src/
# wget http://smalllight.googlecode.com/files/mod_small_light-1.1.1.tar.gz
# tar xzf mod_small_light-1.1.1.tar.gz
# cd mod_small_light-1.1.1
# ./configure --with-apxs=/usr/sbin/apxs \
              --with-imlib2-config=/usr/bin/imlib2-config \
              --with-Wand-config=/usr/bin/MagickWand-config
# make
# paco -D make install

今回は configure のオプションは「--with-apxs」以外なくても多分問題ないんですが、なんとなく明示的に指定してます。

Apache モジュールがインストールされたことを確認します。

# ll /usr/lib64/httpd/modules/mod_small_light.so
-rwxr-xr-x. 1 root root 149748  612 21:25 2013 /usr/lib64/httpd/modules/mod_small_light.so

httpd.conf にも自動的に LoadModule が追加されているはずです。

# cat /etc/httpd/conf/httpd.conf | grep small_light
LoadModule small_light_module /usr/lib64/httpd/modules/mod_small_light.so

LoadModule が設定されているので、apachectl コマンドでモジュールが読み込まれている事を確認できます。

# apachectl -M | grep small_light_module
 small_light_module (shared)

どうやら問題なさそうですね。

使ってみる

mod_small_light を使う為には、以下の Apache モジュールが有効になっている必要があります。

CentOS 6 の base リポジトリから httpd を入れた場合はデフォルトで有効になっているはずですが、もし apachectl -M で確認して表示されないようであれば、事前に有効にしておく必要があります。

次にオリジナル画像を準備します。
縮小することが前提なので、ある程度大きめの画像を適宜用意して下さい。

ここではサーバ上の「/var/images」以下に用意した画像を配置しました。

# mkdir /var/images
# 適当に大きめの画像を配置しておく
# mv ~/kintsuba.jpg /var/images/

画像の用意ができたら httpd.conf を編集します。

# vi /etc/httpd/conf/httpd.conf

以下のルールを設定します。

RewriteEngine on
RewriteRule ^/images/(.+)$ /var/images/$1 [L]
RewriteRule ^/thumbs/(.+)$ /small_light(dw=150,dh=150,ds=s)/$1 [P,L]
RewriteRule ^/small_light[^/]*/(.+)$ /var/images/$1
<LocationMatch ^/small_light[^/]*/>
    SetOutputFilter SMALL_LIGHT
</LocationMatch>

ここでは

  • 「http://サーバ名/images/画像ファイル名.jpg」 でアクセスされた画像はそのまま表示
  • 「http://サーバ名/thumbs/画像ファイル名.jpg」 でアクセスされた画像は 150x150 に縮小して表示

としています。
httpd.conf を保存したら文法チェックをして Apache を起動します。

# apachectl configtest
Syntax OK
# service httpd restart

それではいよいよブラウザからアクセスしてみます。
/images/ でアクセスするとこんな感じでオリジナルの大きい画像が表示されます。

同じ画像に対して /thumbs/ でアクセスするとこんな感じ。

ちゃんと小さくなってますね。

デフォルトではアスペクト比は崩れないようになっています。
アスペクト比を無視して縮小するようにするには、以下のように /thumbs/ の RewriteRule に da=n オプションを追加します。

RewriteRule ^/thumbs/(.+)$ /small_light(dw=150,dh=150,ds=s,da=n)/$1 [P,L]

追加したら Apache を再起動て、再度 /thumbs/ を付けてアクセスしてみます。

今度はアスペクト比を無視して画像が正方形になりました。

次は URL で画像サイズを指定できるようにしてみます。
/thumbs/ の RewriteRule を以下のように書き換えて Apache を再起動してください。

RewriteRule ^/thumbs/w/([0-9]+)/h/([0-9]+)/(.+)$ /small_light(dw=$1,dh=$2,da=n,ds=s)/$3 [P,L]

「http://サーバ名/thumbs/w/画像の幅/h/画像の高さ/画像ファイル名.jpg」という形式の URL でアクセスすることで、自由に画像サイズを指定できるようになっています。

この他にも以下に書いてあるように、いろいろなオプションを指定できるようです。

PatternString
http://code.google.com/p/smalllight/wiki/PatternString

このモジュールを使えば、デザイン変更の際などにサイズの異なる画像をいちいち用意する必要がなくなるのでとっても便利そうですね。
もっと早く試しておけば良かったな。

Nginx に移植した ngx_small_light というモジュールもあるそうなので、そのうちそっちも試してみたいと思います。
-> 試しました。

ちなみに本文とは関係ないですが、写真の猫は実家で飼っている愛猫のきんつばです。
もうおじいちゃん猫ですがとても人懐っこくて可愛いです。