package image_getsize; return 1; #------------------------------------------------------------------------------ # 画像サイズ取得ライブラリ @ FilePath # Ver 1.0.0 # # 画像ファイルの大きさをピクセル単位で返します。 # &image_getsize(); # # return # => (<タイプ>,<高さ>,<幅>) # # 一応 jpg,png,bmp,gifに対応しているが、未保証です(^^; # # <例> # ($type,$h,$w) = &image_getsize("./image.jpg"); # # Copyright 2002 # LunarNight # lunar-night@ninus.ocn.ne.jp # http://www.age.jp/~lunar # #------------------------------------------------------------------------------ #------------------------# #--画像フォーマットメモ--# #------------------------# # #GIG # OFFSET 6 から 2 btyes に幅 # OFFSET 8 から 2 bytes に高さ # ただし、この場合リトルエンディアン # #BMP ファイルは # OFFSET 18 から 4 バイト に幅 # OFFSET 22 から 4 バイト に高さ # ただし、この場合リトルエンディアン # #JPEG -ベースラインJPEG- ファイルの場合 # SOFn マーカー FFC0 (Hex) を見つけてここから始まる # SoF0 セグメント FF の位置を0 として相対オフセット # 位置 5 から、2Bytes に高さ 7 から 2Bytesに幅 # #-インタレースの場合はマーカーがFFC2になる- # #PNG # OFFSET 16 から 4Bytes で幅 # OFFSET 20 から 4Bytes で高さ # #------------------------------------------------------------------- # #※効率のよいJpegマーカー探し #FF で始まるマーカーの次は必ず、そのマーカー分を除いた、セグメント内 #データ長(Bytes数)を格納した 2Bytes が続く # #従って、FF をみつけたら、次の1バイトを取って、それが目的のマーカー #でなければ、次の2バイトを取って、そこにある Bytes数だけ相対的に #seekして、そのセグメントを丸ごとスキップ。 # #そして、スキップした後の直後の位置には必ず次のセグメントのマーカー #があるから、あとは、目的のマーカーにたどり着くまで、同様の方法 #でビュンビュンスキップ。 # #もし、目的のマーカー(FF C0)に到達したならば、そこから、相対的に 3 #Bytes 分、seek 。そこから、2Bytes に高さ、続いて、2Bytes に幅 #を取得できる # # インタレースの場合はマーカーがffc2になるだけ # sub main::image_getsize{ $target = $_[0]; $res = &get_type($target); if ($res eq "jpg"){ ($h,$w) = &jpg_getsize($target);} elsif($res eq "png"){ ($h,$w) = &png_getsize($target);} elsif($res eq "gif"){ ($h,$w) = &gif_getsize($target);} elsif($res eq "bmp"){ ($h,$w) = &bmp_getsize($target);} else { ($h,$w) = ("error","error"); } #---エラー認識 if ($h eq "" || $w eq ""){ ($res,$h,$w) = ("error","error","error");} return($res,$h,$w); } #---画像タイプ認識 sub get_type{ $file = $_[0]; open(FILE,$file); read(FILE,$data,4); close(FILE); ($type)=unpack("H4",$data); if ($type eq "ffd8"){ $type = "jpg"; } elsif($type eq "8950"){ $type = "png"; } elsif($type eq "424d"){ $type = "bmp"; } elsif($type eq "4749"){ $type = "gif"; } else { $type = "unknown";} return($type); } sub gif_getsize{ $gif = $_[0]; open(GIF,$gif); seek(GIF,6,0); read(GIF,$size,4); close(GIF); ($width,$height)=unpack("vv",$size); return($height,$width); } sub bmp_getsize{ $bmp = $_[0]; open(BMP,$bmp); seek(BMP,18,0); read(BMP,$size,8); close(BMP); ($width, $height) = unpack("V2", $size); return($height,$width); } sub jpg_getsize{ $jpg = $_[0]; $now=2; open(JPG,$jpg); seek(JPG,$now,0); while(! eof(JPG)){ #---マーカーチェック read(JPG,$maker,2); $now += 2; ($w1) = unpack("H4",$maker); if ($w1 ne "ffc2" && $w1 ne "ffc0"){ read(JPG,$jump,2); $now += 2; ($s1) = unpack("n",$jump); $now += $s1-2; seek(JPG,$now,0); }else{ $now += 3; seek(JPG,$now,0); read(JPG,$size,4); ($height,$width) = unpack("nn",$size); seek(JPG,0,2); } } close(JPG); return($height,$width); } sub png_getsize{ $png = $_[0]; open(PNG,$png); seek(PNG,16,0); read(PNG,$size,8); close(PNG); ($dummy,$width,$height)=unpack("nnNN",$size); return($height,$width); }