WebP画像変換 – cwebp を自前コンパイル

前回、画像処理のGDを WebP 対応にしてもエックスサーバーで動作しなかったことを書きました。

エックスサーバーで GDを使って WebP を処理するのは諦め、Google で配布している cwebp という JPG/PNG 画像を WebP にコンバートするユーティリティが使えないか試してみました

コンパイル済み cwebp を試す

エックスサーバーではSSHが使えるので、ホームディレクトリに cwebp のコンパイル済みファイルを取得して、コマンドラインから動作するか試してみました

libwebp や cwebpユーティリティは、 downloads repository から取得できます

エックスサーバーでSSHを使い libwebp-1.0.1-linux-x86-64.tar.gz をホームディレクトリにダウンロードして cwebp 実行してみるもエラー発生

cwebp: error while loading shared libraries: libXi.so.6

何かライブラリが不足しているようです

ググってみると

libXi は、X Window System クライアントに X プロトコルの XINPUT 拡張へのイン ターフェースを提供 とのこと

Linux のディストリビューションの違いでしょうか、残念ながらこんなライブラリはエックスサーバーでは入ってないよ

使えないじゃない … (^_^;)

Vagrant で libwebp コンパイル

ソースからコンパイルすれば、何とかなるかもと思い、とりあえず Vagrant 上でソースコードから libwebp コンパイルしてみる

ここに書かれているとおりに作業していきます

まずはソースコード libwebp-1.0.1.tar.gz を取得

$ wget https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.0.1.tar.gz

解凍して展開

$ tar -xvzf libwebp-1.0.1.tar.gz

展開したディレクトリに移り

$ cd libwebp-1.0.1

ホームディレクトリに構築 prefix で構築先を指定

$ ./configure --prefix=$HOME/libwebp

いろいろチェックされて Makefile が生成されたら make を実行します

$ make

しばらくすると /home/vagrant/tmp/libwebp-1.0.1/examples にライブラリと cwebp 実行ユーティリティが生成されます

作成されたライブラリ等をインストール

$ make install

/home/vagrant/libwebp ディレクトリ下にコマンドやライブラリがコピーされて構築されました

これで、Vagrant 上では libwebp が使えるようになり、もちろん cwebp も実行できます

自前コンパイルした cwebp を試す

次に、作成したライブラリ等がエックスサーバーへ持っていき使えるか試してみたところやはりエラーが発生

でも、前とはちょっと様子が変わった感じ

ldd で cwebp の共有ライブラリを見てみるとlibwebp ライブラリが認識できていないだけのようです

先ほどの Google Developers の Compiling the Utilities ページにも書かれていました

This builds and installs the cwebp and dwebp command line tools, along with the libwebp libraries (dynamic and static).

These tools are usually installed under /usr/local/bin/ by default. The local versions are built under the examples/ directory.

The library will usually be installed under the /usr/local/lib/ directory. To avoid run-time errors, make sure that your LD_LIBRARY_PATH environment variable includes this location. The C headers are typically installed under /usr/local/include/webp.

これにより、libwebpライブラリ(動的および静的)とともに、cwebpおよびdwebpコマンドラインツールが構築およびインストールされます。 これらのツールは通常デフォルトで/ usr / local / bin /の下にインストールされます。 ローカルバージョンはexamples /ディレクトリの下に構築されています。 ライブラリは通常/ usr / local / lib /ディレクトリの下にインストールされます。 実行時エラーを回避するには、LD_LIBRARY_PATH環境変数にこの場所が含まれていることを確認してください

ホームディレクトリ下の libwebp/bin にパスを通して、ライブラリが見つかるよう LD_LIBRARY_PATH に libwebp/lib を追加指定すればなんとか動くようです

ただし、動作させるためには、SSHが使える必要あるし、いろいろ手間がかかりすぎ

また、php からは exec を使って cwebp を実行したいのですが、なぜだかライブラリ libwebp.so が見つけられないようで exec がエラーになってしまいます (>_<)

libwebp の静的リンクに挑戦

こうなったら、もう cwebp コマンドだけ使えればいいので、make のオプションを変更して libwebp を静的リンクするのが一番良さそうです

そこで makeファイルを調べたものの複雑すぎてわからない…

仕方がないので、make で実行コマンドの様子を表示させてあたりをつけます

どうやら libtool なるものを使用しており、共有ライブラリと静的ライブラリ用の両方でコンパイルしてくれているようです

make[1]: Entering directory `/home/vagrant/tmp/libwebp-1.0.1/examples'
depbase=`echo example_util.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\
/bin/sh ../libtool  --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I. -I../src/webp  -DNDEBUG -I../src -I../src  -fvisibility=hidden -Wall -Wdeclaration-after-statement -Wextra -Wformat -Wformat-nonliteral -Wformat -Wformat-security -Wmissing-declarations -Wmissing-prototypes -Wold-style-definition -Wshadow -Wundef -Wunreachable-code -Wunused-but-set-variable -Wunused -Wvla -g -O2 -pthread -MT example_util.lo -MD -MP -MF $depbase.Tpo -c -o example_util.lo example_util.c &&\
mv -f $depbase.Tpo $depbase.Plo
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I../src/webp -DNDEBUG -I../src -I../src -fvisibility=hidden -Wall -Wdeclaration-after-statement -Wextra -Wformat -Wformat-nonliteral -Wformat -Wformat-security -Wmissing-declarations -Wmissing-prototypes -Wold-style-definition -Wshadow -Wundef -Wunreachable-code -Wunused-but-set-variable -Wunused -Wvla -g -O2 -pthread -MT example_util.lo -MD -MP -MF .deps/example_util.Tpo -c example_util.c  -fPIC -DPIC -o .libs/example_util.o
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I../src/webp -DNDEBUG -I../src -I../src -fvisibility=hidden -Wall -Wdeclaration-after-statement -Wextra -Wformat -Wformat-nonliteral -Wformat -Wformat-security -Wmissing-declarations -Wmissing-prototypes -Wold-style-definition -Wshadow -Wundef -Wunreachable-code -Wunused-but-set-variable -Wunused -Wvla -g -O2 -pthread -MT example_util.lo -MD -MP -MF .deps/example_util.Tpo -c example_util.c -o example_util.o >/dev/null 2>&1
/bin/sh ../libtool  --tag=CC   --mode=link gcc -fvisibility=hidden -Wall -Wdeclaration-after-statement -Wextra -Wformat -Wformat-nonliteral -Wformat -Wformat-security -Wmissing-declarations -Wmissing-prototypes -Wold-style-definition -Wshadow -Wundef -Wunreachable-code -Wunused-but-set-variable -Wunused -Wvla -g -O2 -pthread   -o libexample_util.la  example_util.lo ../src/libwebp.la
libtool: link: ar cru .libs/libexample_util.a .libs/example_util.o
libtool: link: ranlib .libs/libexample_util.a
libtool: link: ( cd ".libs" && rm -f "libexample_util.la" && ln -s "../libexample_util.la" "libexample_util.la" )
gcc -DHAVE_CONFIG_H -I. -I../src/webp  -DNDEBUG -I../src -I../src -DWEBP_HAVE_JPEG -I/usr/include/libpng15 -DWEBP_HAVE_PNG  -fvisibility=hidden -Wall -Wdeclaration-after-statement -Wextra -Wformat -Wformat-nonliteral -Wformat -Wformat-security -Wmissing-declarations -Wmissing-prototypes -Wold-style-definition -Wshadow -Wundef -Wunreachable-code -Wunused-but-set-variable -Wunused -Wvla -g -O2 -pthread -MT dwebp-dwebp.o -MD -MP -MF .deps/dwebp-dwebp.Tpo -c -o dwebp-dwebp.o `test -f 'dwebp.c' || echo './'`dwebp.c
mv -f .deps/dwebp-dwebp.Tpo .deps/dwebp-dwebp.Po
/bin/sh ../libtool  --tag=CC   --mode=link gcc -fvisibility=hidden -Wall -Wdeclaration-after-statement -Wextra -Wformat -Wformat-nonliteral -Wformat -Wformat-security -Wmissing-declarations -Wmissing-prototypes -Wold-style-definition -Wshadow -Wundef -Wunreachable-code -Wunused-but-set-variable -Wunused -Wvla -g -O2 -pthread   -o dwebp dwebp-dwebp.o libexample_util.la ../imageio/libimagedec.la ../imageio/libimageenc.la ../imageio/libimageio_util.la ../src/libwebp.la -L/usr/lib64 -lpng15 -ljpeg
libtool: link: gcc -fvisibility=hidden -Wall -Wdeclaration-after-statement -Wextra -Wformat -Wformat-nonliteral -Wformat -Wformat-security -Wmissing-declarations -Wmissing-prototypes -Wold-style-definition -Wshadow -Wundef -Wunreachable-code -Wunused-but-set-variable -Wunused -Wvla -g -O2 -pthread -o .libs/dwebp dwebp-dwebp.o  ./.libs/libexample_util.a ../imageio/.libs/libimagedec.a /home/vagrant/tmp/libwebp-1.0.1/src/demux/.libs/libwebpdemux.so /home/vagrant/tmp/libwebp-1.0.1/src/.libs/libwebp.so -lm ../imageio/.libs/libimageenc.a ../imageio/.libs/libimageio_util.a ../src/.libs/libwebp.so -L/usr/lib64 -lpng15 -ljpeg -pthread -Wl,-rpath -Wl,/home/vagrant/libwebp/lib
gcc -DHAVE_CONFIG_H -I. -I../src/webp  -DNDEBUG -I../src -I../src  -fvisibility=hidden -Wall -Wdeclaration-after-statement -Wextra -Wformat -Wformat-nonliteral -Wformat -Wformat-security -Wmissing-declarations -Wmissing-prototypes -Wold-style-definition -Wshadow -Wundef -Wunreachable-code -Wunused-but-set-variable -Wunused -Wvla -g -O2 -pthread -MT cwebp-cwebp.o -MD -MP -MF .deps/cwebp-cwebp.Tpo -c -o cwebp-cwebp.o `test -f 'cwebp.c' || echo './'`cwebp.c
mv -f .deps/cwebp-cwebp.Tpo .deps/cwebp-cwebp.Po
/bin/sh ../libtool  --tag=CC   --mode=link gcc -fvisibility=hidden -Wall -Wdeclaration-after-statement -Wextra -Wformat -Wformat-nonliteral -Wformat -Wformat-security -Wmissing-declarations -Wmissing-prototypes -Wold-style-definition -Wshadow -Wundef -Wunreachable-code -Wunused-but-set-variable -Wunused -Wvla -g -O2 -pthread   -o cwebp cwebp-cwebp.o libexample_util.la ../imageio/libimageio_util.la ../imageio/libimagedec.la ../src/libwebp.la -ljpeg -L/usr/lib64 -lpng15
libtool: link: gcc -fvisibility=hidden -Wall -Wdeclaration-after-statement -Wextra -Wformat -Wformat-nonliteral -Wformat -Wformat-security -Wmissing-declarations -Wmissing-prototypes -Wold-style-definition -Wshadow -Wundef -Wunreachable-code -Wunused-but-set-variable -Wunused -Wvla -g -O2 -pthread -o .libs/cwebp cwebp-cwebp.o  ./.libs/libexample_util.a ../imageio/.libs/libimageio_util.a ../imageio/.libs/libimagedec.a /home/vagrant/tmp/libwebp-1.0.1/src/demux/.libs/libwebpdemux.so /home/vagrant/tmp/libwebp-1.0.1/src/.libs/libwebp.so -lm ../src/.libs/libwebp.so -ljpeg -L/usr/lib64 -lpng15 -pthread -Wl,-rpath -Wl,/home/vagrant/libwebp/lib

肝心の cwebp をリンクしている部分

libtool: link: gcc -fvisibility=hidden -Wall -Wdeclaration-after-statement -Wextra -Wformat -Wformat-nonliteral -Wformat -Wformat-security -Wmissing-declarations -Wmissing-prototypes -Wold-style-definition -Wshadow -Wundef -Wunreachable-code -Wunused-but-set-variable -Wunused -Wvla -g -O2 -pthread -o .libs/cwebp cwebp-cwebp.o  ./.libs/libexample_util.a ../imageio/.libs/libimageio_util.a ../imageio/.libs/libimagedec.a /home/vagrant/tmp/libwebp-1.0.1/src/demux/.libs/libwebpdemux.so /home/vagrant/tmp/libwebp-1.0.1/src/.libs/libwebp.so -lm ../src/.libs/libwebp.so -ljpeg -L/usr/lib64 -lpng15 -pthread -Wl,-rpath -Wl,/home/vagrant/libwebp/lib

この部分をまねて、libwebp関連の共有ライブラリを静的ライブラリに変更してリンクを実行してみたところ、何とか libwebp が静的にリンク出来たようです (^^♪

libwebp を静的リンクしたので cwebp のサイズが大きくなっています
ldd でチェックするとこんな感じ

JPG, PNG は共有ライブラリを使い、WebP は共有ライブラリを使っていないことがわかります

この cwebp ならエックスサーバーでも面倒な作業をせずに簡単に使用できますので、PHPから JPG/PNG 画像を WebP 画像へ変換することが出来るようになります

以上

レンタルサーバーでWebPを使うために悪戦苦闘した体験を前回と今回の2回にわたって紹介いたしました

ちなみにこれだけだと WordPress からは簡単に扱えないので、今作成している WordPress の新しいテーマから使えるようにして近いうちに公開します

 


まとめ記事紹介

go-to-top