師匠の散歩

きままにPerlでも

画像サイズの取得

画像サイズを取り込む / 参考文献 http://cachu.xrea.jp/perl// checkPicSize.cgi

説明

画像サイズを調べる関数を作成し、Getpicsize.pmに搭載しました。使用方法と説明は以下の通りです。


use Getpicsize;

( $format, $photo_width, $photo_height ) = GetImageSize( $fileName );
sub GetImageSize{
    my ( $IMG, $in ) = @_;
    my ( %SHT, %LNG );
    my ( $buf, $mark, $type, $f_size, $width, $height );
    my ( $TAG, $TYPE, $COUNT, $V_OFFSET, $PK, $ENTRY, $Exif_IFD );
    my ( $endian, $dummy1, $dummy2, $dummy, $EOI, $APP1, $length, $exif );
    my ( $format, $offset, $line, $CODE, $jfif, $i );
    my ;
    my $ntag;

    # 定数
    $mark = pack("C", 0xff);
    %SHT = ( 'II' => 'v', 'MM' => 'n' );
    %LNG = ( 'II' => 'V', 'MM' => 'N' );

    # 初期値
    $endian   = '';
    $width    = -1;
    $height   = -1;
    $format   = '';
    $Exif_IFD = -1;

#    if( $in eq '' ){
#	$in = 'IMG';
#   }
#    $in = 'IMG'; この状態では use strict;でエラーになるため、 全てIMGに展開した。

    open( IMG , $IMG ) || return( '', -1, -1 ); # ファイル名$IMGのIMGを開く

    binmode(IMG);           # バイナリモード
    seek( IMG, 0, 0 );      # 読み込み位置をファイルの先頭から0文字に設定
    read( IMG, $buf, 6 );   # 6バイトを読み込み $buf に格納

    # GIF 形式
    if($buf =~ /^GIF/i){
	$format = 'GIF';
	read( IMG, $buf, 2 );
	$width  = unpack("v*", $buf);
	read( IMG, $buf, 2);
	$height = unpack("v*", $buf);

    # Windows Bit Map 形式
    }elsif($buf =~ /BM/){
	$format = 'BMP';
	seek( IMG, 12, 1 );
	read( IMG, $buf, 8 );
	($width, $height) = unpack("VV", $buf);

    # TIFF 形式
    }elsif( $buf =~ /(II)/ || $buf =~ /(MM)/ ){
	$format = 'TIFF';
	$endian = $1;
	seek( IMG, 0, 0 );
	read( IMG, $buf, 8 );
	( $endian, $dummy1, $offset ) = 
	    unpack( "A2$SHT{$endian}$LNG{$endian}", $buf );

	seek( IMG, $offset, 0 );
	read( IMG, $buf, 2 );
	$ENTRY = unpack( $SHT{$endian}, $buf );

	for( $i = 0 ; $i < $ENTRY ; $i++ ){
	    read( IMG, $buf, 8 );
	    $PK = "$SHT{$endian}$SHT{$endian}$LNG{$endian}";
	    ( $TAG, $TYPE, $COUNT ) = unpack( $PK, $buf );

	    read( IMG, $buf, 4 );
	    ( $TAG != 256 && $TAG != 257 ) and next;
	    if( $TYPE == 3 ){
		$PK = "$SHT{$endian}";
	    }elsif( $TYPE == 4 ){
		$PK = "$LNG{$endian}";
	    }else{
		next;
	    }

	    $V_OFFSET = unpack( $PK, $buf );

	    # Image width and height
	    ( $TAG == 256   ) and ( $width  = $V_OFFSET   );
	    ( $TAG == 257   ) and ( $height = $V_OFFSET   );
	    ( $TAG == 34665 ) and ( $format .= '-EXIF'    );
	}

    # PPM 形式
    }elsif( $buf =~ /^(P[123456])
/ ){
	if( $1 eq 'P1' || $1 eq 'P4' ){
	    $format = 'PBM';
	}elsif( $1 eq 'P2' || $1 eq 'P5' ){
	    $format = 'PGM';
	}else{
	    $format = 'PPM';
	}
	seek( IMG, 0, 0 );
	;
	while(  ){
	    next if ( /^#/ );
	    chomp;
	    ( $width, $height ) = split( /s+/, $_ );
	    last;
	}

    # PNG 形式
    }elsif( $buf =~ /PNG/){
	$format = 'PNG';
	seek( IMG, 8, 0 );

	while(1){
	    read( IMG, $buf, 8 );
	    ( $offset, $CODE ) = unpack( "NA4", $buf );

	    if( $CODE eq 'IHDR' ){
		read( IMG, $buf, 8 );
		( $width, $height ) = unpack( "NN", $buf );
		seek( IMG, $offset-8+4, 1 );
		last;

	    }elsif( $CODE eq 'IEND' ){
		last;

	    }else{
		seek( IMG, $offset+4, 1 );
	    }
	}

    }else{
	# JPEG 形式
	seek( IMG, 0, 0 );
	read( IMG, $buf, 2 );
	( $buf, $type ) = unpack("C*", $buf );
	if( $buf == 0xFF && $type == 0xD8 ){
	    $format = 'JPEG';
	  JPEG:while(read( IMG, $buf, 1 )){
	      if(($buf eq $mark) && read( IMG, $buf, 3 )){
		  $type   = unpack("C*", substr($buf, 0, 1));
		  $f_size = unpack("n*", substr($buf, 1, 2));

		  ( $type == 0xD9 ) and ( last JPEG );
		  ( $type == 0xDA ) and ( last JPEG );

		  if($type == 0xC0 || $type == 0xC2){
		      read( IMG, $buf, $f_size-2 );
		      $height = unpack("n*", substr($buf, 1, 2));
		      $width  = unpack("n*", substr($buf, 3, 2));
		      ( $format =~ /EXIF/ ) and ( last JPEG );

		  }elsif( $type == 0xE1 ){
		      read( IMG, $buf, $f_size-2 );
		      $exif = unpack( "A4", substr( $buf, 0, 4 ) );
		      if( $exif =~ /exif/i ){
			  $format .= '-EXIF';
			  ( $width > 0 && $height > 0 ) and ( last JPEG );
		      }

		  }elsif( $type == 0xE0 ){
		      read( IMG, $buf, $f_size-2 );
		      $jfif = unpack( "A4", substr( $buf, 0, 4 ) );
		      if( $jfif =~ /jfif/i ){
			  $format .= '-JFIF';
		      }

		  }elsif( $type == 0x01 || $type == 0xFF ||
			  ( $type >= 0xD0 && $type < 0xD9 ) ){
		      seek( IMG, -2, 1 );

		  }else{
		      read( IMG, $buf, $f_size-2 );
		  }
	      }
	  }
	}

	if( $width > 0 && $height > 0 ){
	    close( IMG );
	    return( $format, $width, $height );
	}

	# TGA 形式
	seek( IMG, 0, 0 );
	read( IMG, $buf, 18 );
	 = unpack( "CCCvvCvvvvCC", $buf );
	if( $TGA[1] == 0 || $TGA[1] == 1 ){
	    if( $TGA[2] ==  0 || $TGA[2] == 1 || $TGA[2] ==  2 ||
		$TGA[2] ==  3 || $TGA[2] == 9 || $TGA[2] == 10 ||
		$TGA[1] == 11 ){
		$format = 'TGA';
		$width  = $TGA[8];
		$height = $TGA[9];
	    }
	}

    }

    close( IMG );
    return( $format, $width, $height );
}

Result


checkPicSize.cgi // Topに戻る // indexに戻る
Copyright(C) 2009-2021 Grandmaster Last up : 2020/09/18