たまにGDで読み込めないJpegファイルがある件
一応バージョンは下の通り。
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
タグ : GD, Image::Imlib2, perl