akishin999の日記

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

mod_dims で動的に画像リサイズ

Web サーバでの画像自動リサイズ方法をいろいろと調べていたところ、 Apache の mod_dims というモジュールを見つけたので試してみました。

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

依存ライブラリのインストール

依存ライブラリをインストールします。

# yum install httpd-devel libcurl-devel libtool make gcc ImageMagick-devel

ImageMagick は標準の yum リポジトリから入るもの(OpenMP 有効)を使用しました。

mod_dims のインストール

mod_dims-release-3.2.5 の tarball をダウンロードして展開し、中に含まれる autorun.sh を実行します。

# cd /usr/local/src/
# wget https://github.com/beetlebugorg/mod_dims/archive/release/3.2.5.tar.gz -O mod_dims-release-3.2.5.tar.gz
# tar xzf mod_dims-release-3.2.5.tar.gz
# cd mod_dims-release-3.2.5
# ./autorun.sh

これでディレクトリ内に configure スクリプトが生成されます。

しかし、このまま ./configure を実行すると各ライブラリのヘッダファイルが見つからずにエラーになってしまいました。

# ./configure
・
・
・
checking wand/magick-wand.h usability... no
checking wand/magick-wand.h presence... no
checking for wand/magick-wand.h... no
・
・
・
checking httpd.h usability... no
checking httpd.h presence... no
checking for httpd.h... no
configure: error: Apache headers not found.

configure スクリプトの中を見てみると、こういった場合、以下のようなオプションで各ディレクトリを指定できるようです。

Optional Packages:
  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
  --with-pic              try to use only PIC/non-PIC objects [default=use
                          both]
  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
  --with-imagemagick        Specify installation directory for ImageMagick library
  --with-curl        Specify installation directory for Curl library
  --with-apache        Specify installation directory for Apache 2.2.x

ただ、これらのオプションを指定した場合、以下のような感じで、指定ディレクトリ以下にライブラリとヘッダファイルが配置されている事を期待して動作するようでした。

# Check for ImageMagic

# Check whether --with-imagemagick was given.
if test "${with_imagemagick+set}" = set; then
  withval=$with_imagemagick;
    imagemagick_dir=$with_imagemagick
    LDFLAGS+=" -L$imagemagick_dir/lib"
    CFLAGS+=" -I$imagemagick_dir/include/ImageMagick"

else

    CFLAGS+=" -I/usr/local/include/ImageMagick"
    CFLAGS+=" -I/opt/local/include/ImageMagick"

fi
・
・
・
# Check for Apache

# Check whether --with-apache was given.
if test "${with_apache+set}" = set; then
  withval=$with_apache;
    LDFLAGS+=" -L$with_apache/lib"
    CFLAGS+=" -I$with_apache/include"
    # Extract the first word of "apxs", so it can be a program name with args.

CentOS 6 ではディレクトリ構造が上記のようにはなっていないので、ここでは適当なディレクトリを作成し、その下にシンボリックリンクを作成することにします。

# mkdir -p /usr/local/ImageMagick/{include,lib}
# ln -s /usr/lib64/libMagickWand.so /usr/local/ImageMagick/lib/libMagickWand.so
# ln -s /usr/lib64/libMagickCore.so /usr/local/ImageMagick/lib/libMagickCore.so
# ln -s /usr/include/ImageMagick /usr/local/ImageMagick/include/ImageMagick

# mkdir -p /usr/local/httpd/{include,lib,bin}
# ln -s /usr/include/httpd/* /usr/local/httpd/include
# ln -s /usr/include/apr-1/* /usr/local/httpd/include
# ln -s /usr/lib64/httpd/* /usr/local/httpd/lib
# ln -s /usr/sbin/apxs /usr/local/httpd/bin/apxs

以下のようにシンボリックリンクを作成したディレクトリを指定して ./configure を実行します。

# ./configure --with-apache=/usr/local/httpd \
              --with-imagemagick=/usr/local/ImageMagick

どうやら上手く認識されたっぽい。
make してインストールします。

# make
# paco -D make install

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

# ll /usr/lib64/httpd/modules/ | grep libmod_dims.so
-rwxr-xr-x 1 root root 626139  616 18:14 2013 libmod_dims.so

httpd.conf にも LoadModule が追加されていました。

# grep libmod_dims.so /etc/httpd/conf/httpd.conf
LoadModule dims_module        /usr/lib64/httpd/modules/libmod_dims.so

apachectl でもモジュールが読み込まれている事を確認できます。

# apachectl -M | grep dims
 dims_module (shared)
Syntax OK

これでインストールは完了です。

OpenMP の設定

ImageMagickApache から使う際、 OpenMP が有効だと負荷が非常に高くなってしまうという問題があるので、Apache 実行時の環境変数 OMP_NUM_THREADS に 1 を設定しておきました。

/etc/sysconfig/httpd を編集します。

# vi /etc/sysconfig/httpd

OMP_NUM_THREADS に 1 を設定して export します。

export OMP_NUM_THREADS=1

設定を保存したら Apache を起動。

# service httpd start

/proc/$pid/environ を見て環境変数 OMP_NUM_THREADS が設定されていることを確認します。

# strings /proc/`pgrep httpd | head -1`/environ
TERM=xterm
PATH=/sbin:/usr/sbin:/bin:/usr/bin
PWD=/
LANG=C
SHLVL=2
OMP_NUM_THREADS=1
_=/usr/sbin/httpd

多分これで OK なはず。

使ってみる

適当な画像を用意します。
大きめの画像を「/var/images」以下に配置しました。

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

設定ファイルに mod_dims 用の設定を追記します。
ここでは httpd.conf に直接追記はせず、モジュール用の設定ファイルを作成しました。

# vi /etc/httpd/conf.d/dims.conf

以下の設定を記述します。

AddHandler dims-local .gif .jpg .png
DimsAddClient testclient
# ↓は dims 用というわけではないが、画像を /var/images に置いたので必要
Alias /images /var/images

公式のサンプルでは最初からもっといろいろ書いてありますが、ローカルの画像ファイルをリサイズしたい場合は上記のみで可能です。

ここで設定しているのは以下の二点です。

  • AddHandler で dims による処理対象拡張子の登録
  • DimsAddClient でアクセス可能な「Application ID」を登録

mod_dims は簡単なアクセスチェックを行ってくれるようで、ここで設定した Application ID を URL に含める事でリサイズした画像へのアクセスが許可されます。
Application ID が異なる場合、/var/log/httpd/error_log に以下のようなエラーログが出力されるので、何故か上手く表示されない、といった場合には確認してみて下さい。

[Mon Jun 17 09:19:54 2013] [error] [client 192.168.81.1] mod_dims error, 'Application ID is not valid', on request: /images/chimaki.jpg/testclient2/resize/120x120/

設定ファイルを保存したら、文法チェックをして Apache を起動します。

# apachectl configtest
Syntax OK
# service httpd start

これで、「http://サーバ名/images/画像ファイル名/testclient/resize/幅x高さ/」という形式の URL でアクセスすると画像がリサイズされて表示されます。

まずはそのままアクセスしてみるとこんな感じ。

150x150 を指定するとこんな感じ。

ちゃんとリサイズされてますね。

外部サーバの画像を縮小して表示

個人的に面白いと思った機能なんですが、mod_dims では外部のサーバ上に配置してある画像に対してもリサイズなどの処理を行う事が出来たりします。

この機能を試してみるため、以下のように設定ファイルを変更します。

AddHandler dims-local .gif .jpg .png
DimsAddClient testclient
# dims による画像取得を許可するホストのリストを設定
DimsAddWhitelist example.com
# dims に処理させる Location を指定
<Location /dims3/>
    SetHandler dims3
</Location>

Alias /images /var/images

設定ファイルに DimsAddWhitelist を追記し、dims による画像取得を許可するホストのリストを設定します。
サブドメインは * によるワイルドカード指定可、複数指定する場合は半角スペース区切りで並べれば良いようです。

このリストに無いホストの画像をリクエストした場合、/var/log/httpd/error_log に以下のようなエラーログが出力されます。

[Mon Jun 17 10:12:42 2013] [error] [client 192.0.2.10] Requested URL has hostname that is not in the whitelist. (example.jp)

また、dims を呼び出す Location を指定します。

公式のリファレンスでは dims, dims3 など複数設定していましたが、試した限りでは dims3 のみで問題ないようです。
ただし、何故か Location 側の文字列もリファレンス通り「dims3」でないと動作しないようでした。
もしかしてここは固定なのかな??

設定したら Apahce を再起動し、ブラウザから以下の形式の URL でアクセスします。

  • 「http://サーバ名/dims3/testclient/resize/幅x高さ/画像の URL」

URL の末尾に取得したい画像の URL を指定してアクセスする感じ。
これで以下のように別サーバに配置した画像に対して、 dims で処理した結果を取得することができます。

余りこの機能を使うようなサーバ構成は多くないかも知れませんが、なかなか面白い機能だと思いました。

mod_dims は他にも画像のフォーマット変換やトリミングなども出来るなど、結構多機能です。
余り使われている実績がないのか、検索してみても情報が少なめですが、検証した範囲ではそんなに悪くないように思えました。

その他の機能の詳細については以下を参照してみて下さい。

Apache Configuration
https://github.com/beetlebugorg/mod_dims/wiki/Apache-Configuration

mod_dims API and configuration documentation
http://code.google.com/p/moddims/wiki/WebserviceApi


ちなみに本文とは関係ないですが、今回の写真の猫は実家で飼っているちまきとようかんです。