たまにGDで読み込めないJpegファイルがある件

 

gdlogobig
GD Graphics Library

一応バージョンは下の通り。

gd-2.0.35-11.el6.x86_64
gd-devel-2.0.35-11.el6.x86_64
libjpeg-turbo-devel-1.2.1-3.el6_5.x86_64
libjpeg-turbo-1.2.1-3.el6_5.x86_64

画像をURLから読み込んで、リアルタイムに処理して出力したい時、ImageMagickだと重たすぎるので、GDを使うことが多い。

主に利用するのは、perl使いなのでGD.pm
GD – search.cpan.org

だがしかし、

my $i = GD::Image->new($img);

で、画像のデータを渡してもエラーになることがある。

特にエラーは帰ってこなくて単に$iがundefになるだけなので原因もわからない。

ちなみに、new()には、ファイルパスやファイルハンドルなデータそのものが入った変数を渡すことが出来て大変便利にできている。

エラーになる原因は分からないが、エラーになるjpegファイルとエラーにならないjpegファイルをjpeg解析に掛けてみると、あーなんか違うね。なるほどわからん。

OKなjpegファイル

Address  Length Message
00000000 ****** SOI  :Start Of Image ******
00000002 [0010] APP0 :JPEG File Interchange Format Ver 1.1 (JFIF)
                 密度 1:1 単位なし
00000014 [003E] COM  :Comment
                 CREATOR: gd-jpeg v1.0 (using IJG JPEG v80), default quality
00000054 [0043] DQT  :Define Quantization Table
                 00000058 QT0-8bit IJG輝度 画質75
00000099 [0043] DQT  :Define Quantization Table
                 0000009D QT1-8bit IJG色差 画質75
000000DE [0011] SOF0 :Start Of Frame 0 – Baseline DCT
                 105[7] x 89[7] pixel – 24bit color (YCbCr 4:2:0)
                 ComponentID-01 Y  2×2 QT0
                 ComponentID-02 Cb 1×1 QT1
                 ComponentID-03 Cr 1×1 QT1
000000F1 [001F] DHT  :Define Huffman Table
                 000000F5 HT0-DC   汎用輝度HT-DC
00000112 [00B5] DHT  :Define Huffman Table
                 00000116 HT0-AC   汎用輝度HT-AC
000001C9 [001F] DHT  :Define Huffman Table
                 000001CD HT1-DC   汎用色差HT-DC
000001EA [00B5] DHT  :Define Huffman Table
                 000001EE HT1-AC   汎用色差HT-AC
000002A1 [000C] SOS  :Start Of Scan 0-63[00]
                 HT Selector[DC/AC] Y[0/0] Cb[1/1] Cr[1/1]
000002AF ****** Image Data ******
                 Data Size 2,053 bytes
00000AB4 ****** EOI  :End Of Image   ******

NGになるjpegファイルの解析結果

Address  Length Message
00000000 ****** SOI  :Start Of Image ******
00000002 [0010] COM  :Comment
                 Lavc54.63.100.
00000014 [0043] DQT  :Define Quantization Table
                 00000018 QT0-8bit CRC-1C80A47F
00000059 [01A2] DHT  :Define Huffman Table 【汎用ハフマンテーブル】
                 0000005D HT0-DC   汎用輝度HT-DC
                 0000007A HT1-DC   汎用色差HT-DC
                 00000097 HT0-AC   汎用輝度HT-AC
                 0000014A HT1-AC   汎用色差HT-AC
000001FD [0011] SOF0 :Start Of Frame 0 – Baseline DCT
                 120[8] x 90[6] pixel – 24bit color (YCbCr 4:2:0)
                 ComponentID-01 Y  2×2 QT0
                 ComponentID-02 Cb 1×1 QT0
                 ComponentID-03 Cr 1×1 QT0
00000210 [000C] SOS  :Start Of Scan 0-63[00]
                 HT Selector[DC/AC] Y[0/0] Cb[1/1] Cr[1/1]
0000021E ****** Image Data ******
                 Data Size 3,163 bytes
00000E79 ****** EOI  :End Of Image   ******

なんとか解決できないものかと、Image::Imlib2で読み込んで書き出してみることにしてみたら、上手く行った。Image::Imlib2で書き出し直したらうまくGD.pmでも読み込み得るようになった。

#Image::Imlib2で読み込んで書き出してみる
open(FILE,">./tmp/t_$$.jpg");
binmode FILE;
print FILE $img;
close(FILE);
#読み込み
my $image = Image::Imlib2->load("./tmp/t_$$.jpg");
#書き出し
$image->save("./tmp/t_$$.jpg");
#GDで読み込み
$i = GD::Image->new("./tmp/t_$$.jpg");

そして、下がImage::Imlib2でNGファイルを読み込んでから書き出してOKになたものの解析結果。

Address  Length Message
00000000 ****** SOI  :Start Of Image ******
00000002 [0010] APP0 :JPEG File Interchange Format Ver 1.1 (JFIF)
                 密度 1:1 単位なし
00000014 [0043] DQT  :Define Quantization Table
                 00000018 QT0-8bit IJG輝度 画質77
00000059 [0043] DQT  :Define Quantization Table
                 0000005D QT1-8bit IJG色差 画質77
0000009E [0011] SOF0 :Start Of Frame 0 – Baseline DCT
                 120[8] x 90[6] pixel – 24bit color (YCbCr 4:2:0)
                 ComponentID-01 Y  2×2 QT0
                 ComponentID-02 Cb 1×1 QT1
                 ComponentID-03 Cr 1×1 QT1
000000B1 [001F] DHT  :Define Huffman Table
                 000000B5 HT0-DC   汎用輝度HT-DC
000000D2 [00B5] DHT  :Define Huffman Table
                 000000D6 HT0-AC   汎用輝度HT-AC
00000189 [001F] DHT  :Define Huffman Table
                 0000018D HT1-DC   汎用色差HT-DC
000001AA [00B5] DHT  :Define Huffman Table
                 000001AE HT1-AC   汎用色差HT-AC
00000261 [000C] SOS  :Start Of Scan 0-63[00]
                 HT Selector[DC/AC] Y[0/0] Cb[1/1] Cr[1/1]
0000026F ****** Image Data ******
                 Data Size 1,673 bytes
000008F8 ****** EOI  :End Of Image   ******

Image::Imlib2もGD並に高速なので、じゃあ、最初からImage::Imlib2を使えばいいじゃんと思うが、そうもいかない理由がある。それは、Image::Imlib2は画像データの取り込みがファイルの読み込みにしか対応していないからだ。

変数に入った画像を渡して、処理することが出来ないので、一度ファイルを介す必要があるため、面倒だしその為のオーバーヘッドが生じると思われるので、リアルタイムの処理には向かない。用途が違えばImage::Imlib2が最適かもしれない。

それに、共用レンタルサーバの場合はGDは入っていてもImage::Imlib2が入っていない環境も多いと思う。専用サーバやVPSなら関係ないけど。

なので、GD.pmで読み込めなかった時だけImage::Imlib2を使うように処理するようにした。

Image::Imlib2 – search.cpan.org

タグ : , ,