画像の縦横のピクセル数を求める
保存されている画像ファイルの、縦と横のピクセル数を求めるサブルーチンです。 PerlでHTMLを出力するために使用したものなので、画像フォーマットはJPEG、GIF、PNGにのみ対応しています。
ソースコード
# 画像の縦横ピクセル数取得 sub get_imagesize { # エラー報告にCarp.pm use Carp qw(croak); my $filename = shift; # 画像ファイル名 my $rise_error = shift; # エラー処理 my ( $width, $height ); # 戻り値 # ファイルが存在しないとき if ( ! -e $filename ) { if ( $rise_error ) { croak("Cannot find file [$filename]."); } else { return (0,0); } } # オープンできないとき unless ( open( IMG, $filename ) ) { if ( $rise_error ) { croak("Cannot open file [$filename]."); } else { return (0,0); } } binmode(IMG); my $buf; # GIF if( $filename =~ /\.gif$/i ){ read( IMG, $buf, 6 ); if ( $buf =~ /^GIF/ ) { read( IMG, $buf, 2 ); $width = unpack("v*", $buf); read( IMG, $buf, 2); $height = unpack("v*", $buf); } else { croak("GIF Format error") if ( $rise_error ); } } # PNG elsif( $filename =~ /\.png$/i ){ read( IMG, $buf, 8 ); if ( $buf =~ /^\x89PNG/ ) { read ( IMG, $buf, 8 ); my ( $size, $type ) = unpack( "NA4", $buf ); if ( $type ne 'IHDR' ) { read( IMG, $buf, 8 ); ($width, $height) = unpack("NN", $buf); } else { croak("PNG Format error") if ( $rise_error ); } } else { croak("PNG Format error") if ( $rise_error ); } } # JPEG elsif ( $filename =~ /\.jpe?g?$/i ) { seek( IMG, 0, 0 ); read( IMG, $buf, 2 ); # FFD8 = JPEGファイルの先頭 if ( $buf =~ /^\xFF\xD8$/ ) { my $skip_size; # マーカーごとに読む while ( read( IMG, $buf, 2 ) ) { # 画像サイズはFFC0マーカーで記述 if ( $buf =~ /^\xFF\xC0$/ ) { seek( IMG, 3, 1 ); read( IMG, $height, 2 ); $height = unpack("n*", $height); read( IMG, $width, 2 ); $width = unpack("n*", $width); last; } # FFD9 = ファイル終端 # FFDA = イメージデータそのもの elsif ( $buf =~ /\xFF(?:\xD9|\xDA)/ ) { last; } # FFC0にたどり着くまでは読み飛ばす elsif ( $buf =~ /\xFF(?:[\xE0-\xED]|\xFE|\xDB|\xDD|\xC4)/ ) { read( IMG, $buf, 2 ); $skip_size = unpack("n*", $buf) - 2; seek( IMG, $skip_size, 1 ); } } } else { croak("JPEG Format error") if ( $rise_error ); } } # その他 else { croak("Bad filename [$filename]") if ( $rise_error ); } close( IMG ); return( $width, $height ); }
[ ページ先頭へ ]
書式
my ( $width, $height ) = get_imagesize($filename, $rise_err);
引数
- $filename
- 画像ファイル名。
受け取った値でそのままOPENを試みるので、実行ディレクトリからの相対パスか、絶対パスで指定してください。 - $rize_error
-
読取エラーの時に、例外を発生させるかどうかを指定。
1 = 例外発生、0 = 発生させない(デフォルト)。省略した場合、エラー処理は自分で行ってください。
例外を発生させた場合、能動的にそれを拾っていなければ、おそらくプログラムは中断するでしょう。
戻り値
- $width, $height
- 画像の横、縦のピクセル数(数値)。読取に失敗した場合など、正しく読めなかった時は、それぞれ0を返す。
[ ページ先頭へ ]
CGIで利用するなら、多分こんな感じ
# 画像ファイル名はパスつきで指定 my $filename = "../img/someimage.jpg"; # 縦横の画像サイズを取得 my($width, $height) = get_imagesize($filename); # 画像タグを生成 my $image_tag; if ( $width == 0 && $height == 0 ) { $image_tag = qq|(画像の読込に失敗しました)|; } else { $image_tag = qq|<img src="$filename" width="$width" height="$height">|; }
[ ページ先頭へ ]
利用方法、備考
ソースコードを、自分のプログラムにコピーするなどして、ご利用ください。グローバル変数は使っていないので、use strictしていても動作OKなはずです。
サブルーチン内では、画像フォーマットの仕様で定められている(らしい)画像ピクセル数のデータを読み出しています。
画像フォーマットは、ファイル名の拡張子で判断しています。対応している拡張子は「.gif」「.png」「.jpg」「.jpeg」(それぞれ大文字・小文字どちらでも可)です。その後、画像フォーマットが正しいかどうかチェックしています。
正規表現で手を抜いているので、「.jpe」と「.jp」でもJPEGと判断するのはご愛嬌ということで。
最終更新日:2008/09/02
[ ページ先頭へ ]