マクロツイーター

はてダから移行した記事の表示が崩れてますが、そのうちに直せればいいのに(えっ)

ナントカBoxの話(4)

前回の続き)
ビットマップ画像の解像度の話

以前に書いたように、ビットマップ画像を扱う場合でも bbox は「物理的な長さ」で表される。従って、各 DVIウェア/エンジンは各画像ファイルに対して「解像度」を決定して、その上でピクセル数を「物理的な長さ」に変換している。

そのため、普段あまり意識することのない「解像度」を LaTeX ユーザが意識する必要がある場面が生じる。

  1. 自動取得が不可能でユーザが bbox の値を bb オプションキーで指定する場合。
  2. 画像の一部を切り出して挿入するため viewporttrim オプションキーを指定する場合。

エンジンが PDF を直接出力する場合、或いは dvipdfmx で extractbb の自動機能が有効な場合*1はユーザが bbox を指定する必要はないため、1 での問題は起こらない。主に 2 の場合に注意が必要であろう。

(私自身は、ビットマップ画像に対する viewporttrimピクセル単位で指定できた方がいいと考えているが、現在の pdfTeX や XeTeX ではビットマップ画像の解像度を得る手段がないため、*2​((実は pdfTeX では「ビットマップのピクセル単位」の処理を補助するため px という長さ単位が新説されている。しかし、これは単に \pdfpxdimen という寸法パラメタを参照しているだけで、\pdfximage で読み込まれるビットマップ画像とは全く独立である。したがって、ここで述べた用途には役に立たない。))その実現は難しい。)

例によって*3、ビットマップ画像ファイルの解像度の判定の方法は DVIウェア/エンジン毎に異なる。著名なもの(ビットマップ画像の挿入をサポートするもの)について以下で説明する。

pdfTeX/LuaTeX

  • 画像ファイルが解像度情報を持っている場合はそれに従う。
  • そうでない場合、整数パラメタ \pximageresolution の値を見る。0 でない場合、それが dpi 単位の解像度を表す。
  • \pximageresolution が 0 の場合は 72 dpi と見做す。

LaTeX において \pximageresolution の値が既定値の 0 (つまり 72 dpi)から変更されることは無いと思われるので、実質的には次に述べる XeTeX と dvipdfmx と同等と考えられる。(ちなみに、解像度が 72 dpi の時は、bp 単位の数値はピクセル単位のものに(偶然)一致する。)

XeTeX および dvipdfmx

  • 画像ファイルが解像度情報を持っている場合はそれに従う。
  • そうでない場合、72 dpi と見做す。

なお、dvipdfmx を使う場合、LaTeX 自身*4は画像のサイズを判断できないので、.xbb ファイルまたは \includegraphics 命令の bb オプションキーを用いて bbox の値をユーザが与える必要がある。ここで、dvipdfmx 自身は解像度を判定していることに注意されたい。つまり、bbox の値を算出する際にもし dvipdfmx が判定した解像度と異なる値を用いてしまうと、dvipdfmx の処理の内部で齟齬が生じて予想外の結果が生じるかも知れない。

このような解像度の判定も込めて、画像の「dvipdfmx が判定する」bbox の正しい値を示してくれる補助ソフトウェアが extractbb である。*5extractbb は bbox の情報を記したファイルを、元の画像ファイルの拡張子を .xbb を変えた名前で作成する。grahpicx パッケージの dvipdfmx 用のドライバは、この .xbb ファイルを読み込んで bbox の情報を得ることができる。

dvipdfm(参考)

dvipdfmx の前身である dvipdfm での処理は以下のようであった。*6

  • 画像ファイルが持つ解像度情報は無視して、一律に 100 dpi と見做す。

dvipdfmx の extractbb に相当するものとして、dvipdfm には ebb という補助ソフトウェアがあり、これは「dvipdfm が判定する」bbox の正しい値を拡張子 .bb のファイルに書き出す。graphicx パッケージの dvipdfm 用のドライバは、これを読み込んで bbox の情報を得ていた。*7

dviout

dviout ではビットマップ画像に対する viewporttrim オプションキーがサポートされていない。従って、「画像ファイルの解像度」が問題になるのは「bbox の物理的な長さ」が必要な場合に限られる。

例えば、400 px × 200 px で解像度が 96 dpi のビットマップ画像 image.bmp があり、それを次のような special 命令を用いて文書に挿入したとする:

bmpfile=image.bmp

この場合、dviout は画像の解像度の値として「dviout が DVI 文書を表示するのに使用する解像度((dviout-dpi: パラメタの値。))」を仮定する(画像ファイルのもつ情報は無視される)。つまり、当該の DVI 文書を 600 dpi の解像度を設定した dviout で表示した場合、image.bmp も 600 dpi の解像度を持つと仮定される。もしここで dviout の解像度の設定*8を 300 dpi に変更したとすると、image.bmp の解像度も 300 dpi に変化する。すなわち、全く同じ DVI 文書であるのに紙面中で画像が占める領域が dviout の設定によって変わって見えるという奇妙な事態が発生する。

ただし、このような奇妙な動作になるのは、「挿入後の寸法(hsizevsize パラメタ)」が指定されていない場合に限られる。先の例で、もし次のように挿入後の寸法が指定されていたとする:

bmpfile=image.bmp hsize=80 vsize=40

この場合、明らかに挿入した画像は 80 bp × 40 bp の領域を占める。そして、ビットマップ画像の一部を切り出す機能が無いため、画像の「元々の解像度」を参照する必要自体が無くなっているのである。((なお、hsizevsize の一方のみを指定した場合は、画像のアスペクト比(これは「縦横のピクセル数の比」に等しく解像度の影響を受けない)を保つ条件の下で他方の値が決定される。今の例で hsize=80vsize=40 の一方を省略しても全く同じ結果が得られる。))もちろん、dviout の設定によって紙面上の位置が異なるなんて事態も起こらない。

そこで、graphicx パッケージの dviout 用ドライバでは、常に「挿入後の寸法」を special 命令のパラメタに含めるように実装が行われている。既に \includegraphics 命令で「挿入後の寸法(widthheight オプションキー)」が指定されている場合は話は明らかなので、ここではそうでない場合を考える。dviout 用のドライバでは、bbox を自動的に取得する機構はないので、\includegraphics 命令の bb キー(または .bb ファイル)に正しい bbox の値を指定する必要がある。画像 image.bmp は 400 px × 200 px で解像度が 96 dpi であるから、bbox の値は以下のようになる。

\includegraphics[bb=0 0 300 150]{image.bmp}

ドライバは、ユーザが与えた bbox の値を元にして special 命令に挿入後の寸法の指定を追加する。これにより、「画像の元々の寸法」で文書に挿入することが実現される。

bmpfile=image.bmp hsize=300 vsize=150

dvipdfm(x) と同じく、dviout も適切な bbox の値を調べるための手段を用意していて、bmc という補助プログラムを -b オプション付きで呼ぶことで、bbox 情報が記された image.bb ファイルが書き出される。*9

bmc -b:96 image.bmp

ここで、-b: の後に付けている数値は解像度(dpi 単位)であり、省略時(つまり -b と指定した時)の既定値は 72 である。((ただし、-b-b:72 の出力結果は(等価ではあるが)異なる。解像度を省略(-b)した場合は「ピクセル数が単位無し」で出力される(既に説明したようにこれは 72 dpi に相当する)のに対し、解像度を指定した場合(-b:72 も含む)は「in 単位の長さ」で出力される。))ここから解るように、bmc は画像の解像度を判定する機能を持っておらずユーザがそれを指定する必要がある訳である。といっても実は、既に説明した通り、dviout 自体も画像の解像度を全く参照しない(かつ、参照せずに済む処理方式を採用している)。なので、bbox 計算時に用いる解像度は結局何でもよい。そういう訳で、実際には次のように解像度を指定せずに実行されていることが多いようである。

bmc -b image.bmp

*1:および、bmpsize パッケージや mediabb パッケージでの自動取得処理が適用可能な場合。

*2:LuaTeX なら Lua の img ライブラリを利用することで実現できる。

*3:まあ、何せ TeXからしょうがないね。

*4:bmpsize パッケージを使う場合を除く。

*5:環境によっては xbb という別名でも起動できる。

*6:昔(7 年以上前)の dvipdfmx は dvipdfm と同じ仕様であったが、pdfTeX の仕様に合わせる形で仕様変更された。

*7:ちなみに、graphicx の慣習では bbox 情報のファイルの拡張子は .bb とすることになっている。dvipdfmx および extractbb が .xbb という普通と異なる拡張子を用いているのは、古い dvipdfm 用のファイルを誤って読まないようにするためである。

*8:「文書を表示する時の解像度」は TeX 文書(DVI 文書)が持つ属性ではなく dviout の設定の一部であることに注意。

*9:bmc は dviout の画像処理の世界における統合的な補助ユーティリティになっていて、与えるオプションにより色々と異なる動作をする。