画像の縦横のピクセル数を求める
保存されている画像ファイルの、縦と横のピクセル数を求めるサブルーチンです。 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
[ ページ先頭へ ]