[[TeX用語集]]
#author("2017-01-10T11:10:54+09:00","default:hoge","hoge")
[[TeX用語集>TeX/Glossary]]

*** BoundingBox [#v5746b76]
ばうんでぃんぐぼっくす。~
画像ファイルの (x_0, y_0) 座標と (x, y) 座標の組。~

 %%Title: ./file.pdf
 %%Creator: extractbb 20140317
 %%BoundingBox: 0 0 595 841
 %%HiResBoundingBox: 0.000000 0.000000 595.000000 841.000000
 %%CreationDate: Mon Apr 21 10:03:07 2014

同じディレクトリにある画像ファイルの BoundingBox ファイルを
生成したい時は
 extractbb *.pdf *.png *.jpg *.jp2
とでもすれば、PDF, PNG, JPEG, JPEG 2000 の *.xbb がそれぞれ作成される。~

TeX は画像も一つの箱としてしか見ていないので,画像の縦 x 横と原点
が分かればそれで組版できる。~
EPS 画像には 0 0 200 300 のような
BoundingBox 情報が含まれているので,これを使って 200 x 300 の箱を
配置している。~
どのような画像かの詳細については関与していない。~

どのような画像形式であろうが、BoundingBox を指定さえすれば、
TeX は正確に組版できる。~
 \includegraphics[bb= 0 0 200 300]{hoge.xxx}
そして、実際に画像を取り扱うのは 「デバイスドライバ」であって、
このデバイスドライバの能力に依存して取り込める画像形式が決まる。~

dvipdfmx であれば、PDF, EPS, PNG, JPEG, JPEG 2000, BMP, MetaPost が読み込める。~
dvips であれば EPS が読み込める。~

時折、Ghostscript などが正確な BoundingBox が実際の描画領域を
取得してくれない事があるので、PSTricks を使用している時に
問題になる事があります。~
[[PSTricks>PSTricks_on_Dvipdfmx]] で
例えば何らかの図形を描いて、
それを dvips で
 dvips -Ppdf -o fig1.eps input.dvi
とすると fig1.eps が作成されます。こいつの真の BoundingBox を
取得するには
 gs -sDEVICE=pbm fig1.eps -sOutputFile=fig1.pbm
 bbb < fig1.pbm > fig1.bb
などとすると良いでしょう。

bbb は BoundingBox を割り出すようなプログラム,例えば次のような
ものです。
 #include<stdio.h>
 #include<string.h>
 
 #define buf_size 1024
 
 struct bb {  unsigned int width, height; };
 
 int main ( void ){
   struct bb max, min, orig;
   int ch;
   int i, j;
   char bufa[buf_size];
 
   scanf( "%s\n", bufa);
   if( !(strcmp(bufa, "P1") == 0 ) ){
     fprintf(stderr, "Error!! Please give me correctly PGM file." );
     return 0;
   }
   gets ( bufa );
   scanf ( "%d%d", &orig.width, &orig.height );
 
   max.width=0;
   max.height=0;
   min.width=orig.width;
   min.height=orig.height;
   
   for( j=0; j < orig.height;  j++){
     for( i=0; i < orig.width; i++){
       ch = getchar();
       if ( ch == '\n' ){
        i--;
       }else if( ch == '1' ){
        if ( i < min.width )
          min.width = i;
        if ( j < min.height )
          min.height = j;
        if ( i > max.width ) 
          max.width = i;
        if ( j > max.height )
          max.height= j;
       }
     }
   }
 
   printf ("%%%%BoundingBox: %d %d %d %d\n", 
          min.width - 1, orig.height - max.height - 1, 
          max.width + 1, orig.height - min.height + 1);
 
   return 0;
 }

通常の BoundingBox を算出するようなプログラムは線のギリギリの部分で
BoundingBox を取ろうとするので,線が書けてしまう事があります。~
さらに、EPS に記述されている情報だけを取得するので
 %%BoudingBox: 0 0 300 200 
というコメント行があれば、それしか参照しません。~
しかし、
 draw circle (300, 200);
のように (300, 200) の座標に 円を描け、という場合には対応できません。~
ですから、正確な BoundingBox を取得するためには実際にその画像が
最終的にどのように描かれるのかを知らなければならないと言うことになります。~

おまけとして,
上記は C 言語のものですが、perl では次のように書けます。~
 #!/usr/bin/perl -w
 
 $max_height = $max_width = $min_height = $min_width = $org_height = $org_width = 0;
 $i = $j = 0;
 $ch = 0;
  
 while (<>){
     last if (/^P1/);
     if (/^P?/){ print "Error!! Please give me correctly PGM file.\n"; exit;}
 }
 
 while (<>){
     next if (/^\#/);
     if (/(\d+) (\d+)/){
        $org_width = $1; 
        $org_height = $2;
        last;
     }
 }
 
 $min_width = $org_width;
 $min_height = $org_height;
 
 for ($j = 0; $j < $org_height;  $j++){
     for ($i = 0; $i < $org_width; $i++){
        read STDIN, $ch, 1;
        if ( $ch eq '0' ){
        } elsif ( $ch eq '1' ){
            if ($i < $min_width) {$min_width = $i;}
            if ($j < $min_height){$min_height = $j;}
            if ($i > $max_width) {$max_width = $i;}
            if ($j > $max_height){$max_height= $j;}
        } else {
            $i--;
        }
     }
 }
 
 printf "\%\%\%\%BoundingBox: %d %d %d %d\n", 
     $min_width - 1, $org_height - $max_height - 1, 
     $max_width + 1, $org_height - $min_height + 1;
 
 exit;