Symfoware

Symfowareについての考察blog

PHPで画像リサイズの高速化(setOption,libjpeg-turbo使用)

PHPで画像のリサイズを試してみました。
PHPで画像リサイズ(ImageMagick, GD使用)

リサイズ処理にそれなりの時間が必要なので、高速化できないか調べてみます。


現状の把握



100回リサイズ処理を実行して処理時間を計測してみます。
リサイズに使用する画像は前回同様の約10MBのファイルです。

ImageMagick版


  1. <?php
  2. function do_resize() {
  3.     // 縦横、1600pxに収まるように縮小したい
  4.     $width = 1600;
  5.     $height = 1600;
  6.     $image = new Imagick('sample.jpg');
  7.     // オリジナルのサイズ取得
  8.     $width_org = $image->getImageWidth();
  9.     $height_org = $image->getImageHeight();
  10.     // 縮小比率を計算
  11.     $ratio = $width_org / $height_org;
  12.     if ($width / $height > $ratio) {
  13.         $width = $height * $ratio;
  14.     } else {
  15.         $height = $width / $ratio;
  16.     }
  17.     // 縮小実行
  18.     $image->scaleImage($width, $height);
  19.     // GDの機能で保存する
  20.     $write_image = ImageCreateFromString($image->getImageBlob());
  21.     ImageJpeg($write_image, 'result.jpg', 80);
  22. }
  23. $time_start = microtime(true);
  24. for ($i = 0; $i < 100; $i++) {
  25.     do_resize();
  26. }
  27. $timelimit = microtime(true) - $time_start;
  28. echo $timelimit . " seconds\n";




GD版


  1. <?php
  2. function do_resize() {
  3.     // 縦横、1600pxに収まるように縮小したい
  4.     $width = 1600;
  5.     $height = 1600;
  6.     //JPEGファイルを読み込む
  7.     $image = ImageCreateFromJPEG('sample.jpg');
  8.     // 元画像のファイルサイズを取得
  9.     $original_width = ImageSx($image);
  10.     $original_height = ImageSy($image);
  11.     //元画像の比率を計算し、高さを設定
  12.     $proportion = $original_width / $original_height;
  13.     $height = $width / $proportion;
  14.         
  15.     //高さが幅より大きい場合は、高さを幅に合わせ、横幅を縮小
  16.     if($proportion < 1){
  17.         $height = $width;
  18.         $width = $width * $proportion;
  19.     }
  20.     $new_image = ImageCreateTrueColor($width, $height); // 画像作成
  21.     // 元画像から再サンプリング
  22.     ImageCopyResampled($new_image, $image,0,0,0,0,$width,$height,$original_width,$original_height);
  23.     // 保存
  24.     ImageJpeg( $new_image , 'result.jpg' , 80 );
  25. }
  26. $time_start = microtime(true);
  27. for ($i = 0; $i < 100; $i++) {
  28.     do_resize();
  29. }
  30. $timelimit = microtime(true) - $time_start;
  31. echo $timelimit . " seconds\n";




ImageMagick版が84.80秒
GD版が78.83秒という結果になりました。

GDの方が若干高速ですね。






setOption



本当は速いImageMagick: サムネイル画像生成を10倍速くする方法

こちらを参考に、jpeg:sizeオプションをつけて画像を開くようにしてみます。


  1. <?php
  2. function do_resize() {
  3.     // 縦横、1600pxに収まるように縮小したい
  4.     $width = 1600;
  5.     $height = 1600;
  6.     //$image = new Imagick('sample.jpg');
  7.     $image = new Imagick();
  8.     $image->setOption('jpeg:size', '1600x1600');
  9.     $image->readImage('sample.jpg');
  10.     // オリジナルのサイズ取得
  11.     $width_org = $image->getImageWidth();
  12.     $height_org = $image->getImageHeight();
  13.     // 縮小比率を計算
  14.     $ratio = $width_org / $height_org;
  15.     if ($width / $height > $ratio) {
  16.         $width = $height * $ratio;
  17.     } else {
  18.         $height = $width / $ratio;
  19.     }
  20.     // 縮小実行
  21.     $image->scaleImage($width, $height);
  22.     // GDの機能で保存する
  23.     $write_image = ImageCreateFromString($image->getImageBlob());
  24.     ImageJpeg($write_image, 'result.jpg', 80);
  25. }
  26. $time_start = microtime(true);
  27. for ($i = 0; $i < 100; $i++) {
  28.     do_resize();
  29. }
  30. $timelimit = microtime(true) - $time_start;
  31. echo $timelimit . " seconds\n";




結果は46.24秒。
ほんとに高速化された。





GD + libjpeg-turbo



libjpeg-turboというjpegファイル読み込みを高速化するモジュールがあるそうです。

libjpeg-turboがいいらしい
Ubuntuにlibjpeg-turboを入れて、JPEG画像の読み込み・変換を高速化

以下を参考に、phpをソースからDebian 7に入れてみます。

PHP 5 のインストール
インストール手順


比較のため
・通常版
・libjpeg-turbo版
の2つをビルドしました。

手順をざっとメモしておきます。


必要なライブラリをインストール。


# apt-get install g++ make
# apt-get install libxml2-dev libpng12-dev zlib1g-dev libjpeg8-dev




phpのソースを取得し展開。


# cd /usr/local/src
# wget -O php-5.6.4.tar.gz http://jp1.php.net/get/php-5.6.4.tar.gz/from/this/mirror
# tar zxf php-5.6.4.tar.gz




適当にフォルダをリネーム。
これを通常版としてビルドします。


# mv php-5.6.4 php-5.6.4-normal
# cd php-5.6.4-normal




configureオプションは以下のとおり。
/opt/php-5.6.4-normalにインストールすることにしました。


# ./configure --prefix=/opt/php-5.6.4-normal --enable-mbstring --with-gd --with-zlib --with-jpeg-dir=/usr/local/lib/
# make && make install




次はlibjpeg-turboを使用する版です。
依存ライブラリのインストールと、libjpeg-turboのソースを取得。


# apt-get install nasm
# cd /usr/local/src
# wget -O libjpeg-turbo-1.3.1.tar.gz http://sourceforge.net/projects/libjpeg-turbo/files/1.3.1/libjpeg-turbo-1.3.1.tar.gz/download
# tar zxf libjpeg-turbo-1.3.1.tar.gz



/opt/libjpeg-turbo/にlibjpeg-turboをインストールします。


# cd libjpeg-turbo-1.3.1
# ./configure --prefix=/opt/libjpeg-turbo/
# make && make install





phpのソースを再度展開。
これをlibjpeg-turbo用にしました。


# cd /usr/local/src
# tar zxf php-5.6.4.tar.gz
# mv php-5.6.4 php-5.6.4-turbo
# cd php-5.6.4-turbo




configureオプションはこうなります。


# ./configure --prefix=/opt/php-5.6.4-turbo --enable-mbstring --with-gd --with-zlib --with-jpeg-dir=/opt/libjpeg-turbo/
# make && make install




ちゃんとビルドできたか確認します。


# /opt/php-5.6.4-normal/bin/php -i | more




通常版は、gdのlibJPEG Versionが8になります。


gd

GD Support => enabled
GD Version => bundled (2.1.0 compatible)
GIF Read Support => enabled
GIF Create Support => enabled
JPEG Support => enabled
libJPEG Version => 8
PNG Support => enabled
libPNG Version => 1.2.49
WBMP Support => enabled
XBM Support => enabled





# /opt/php-5.6.4-turbo/bin/php -i | more




turobo版は、gdのlibJPEG Versionが6bになります。


gd

GD Support => enabled
GD Version => bundled (2.1.0 compatible)
GIF Read Support => enabled
GIF Create Support => enabled
JPEG Support => enabled
libJPEG Version => 6b
PNG Support => enabled
libPNG Version => 1.2.49
WBMP Support => enabled
XBM Support => enabled





ちゃんとビルドできた模様。
こんな感じで、動かすphpを切り替えてテストしてみます。


# /opt/php-5.6.4-normal/bin/php test_gd.php
# /opt/php-5.6.4-turbo/bin/php test_gd.php




通常版は104.79秒
turbo版は89.50秒でした。

turbo版の方が高速なのですが、aptでインストールしたライブラリより成績悪いです。
configureオプションがまずいのかな?



結果をまとめると以下のとおり。

バージョン100件の処理時間
ImageMagick84.80秒
GD78.83秒
ImageMagick + setOption46.24秒
GD 5.6.4通常104.79秒
GD 5.6.4 libjpeg-turbo89.50秒






別の画像サンプル



9.9 MB、5472x3648の画像データをサンプルとして使っていましたが、
ちょっと小さいサイズでも試してみます。

http://matome.naver.jp/odai/2130656175532536701/2130708549544398603
こちらの画像をお借りました。
363.2KB、1920x1200のデータです。

バージョン100件の処理時間
ImageMagick19.56秒
GD18.36秒
ImageMagick + setOption35.20秒
GD 5.6.4通常26.40秒
GD 5.6.4 libjpeg-turbo22.54秒


ImageMagick、オプション指定したほうが遅くなるようです。
元画像のサイズと、縮小したいサイズを加味してどの方法を採用するか
検討したほうが良さそうです。








【参考URL】

PHPで処理実行速度を計測する方法

本当は速いImageMagick: サムネイル画像生成を10倍速くする方法

libjpeg-turboがいいらしい

Ubuntuにlibjpeg-turboを入れて、JPEG画像の読み込み・変換を高速化

PHP 5 のインストール

インストール手順
関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2015/01/11(日) 15:49:12|
  2. PHP
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
<<Java + MockFtpServerでFTPサーバー側のプログラムを作成する その1 | ホーム | PHPで画像リサイズ(ImageMagick, GD使用)>>

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://symfoware.blog68.fc2.com/tb.php/1579-ec4dfe17
この記事にトラックバックする(FC2ブログユーザー)