日本人のための LaTeX タブー集 ~画像読込編~

  • 187
    Like
  • 5
    Comment

長い前置き

今年(2013年)の3月に、「使ってはいけない LaTeX のコマンド・パッケージ・作法」という記事が公開され、LaTeX 使用者の間で少し話題になっているようです。記事の中でも述べられているように、その記事の内容は CTAN で「l2tabu パッケージ」として公開されている“An Essential Guide to LaTeX2e Usage”という文書1からの抜粋となっています。この文書は TeX Live にも含まれていて、texdoc l2tabuen を実行すると PDF を読むことができます。

しかし、l2tabu は欧米のユーザの間でまとめ上げられた「タブー集」ですので、欧米とは異なる事情をもつ日本人に特有の事項については当然ながら触れられていません。そこで、このような「日本人のためのタブー集」を紹介しようと思います。初回となる本記事では画像の取り扱い、すなわち graphicx パッケージの使用に関するタブーを集めました。(なおここの内容は graphicx と graphics パッケージの両方に当てはまります。)

画像の取扱に関しては日本も海外も関係ないじゃないかというと、残念ながらそうはいえません。海外では pdfTeX で一発で TeX 文書を PDF に変換するのが一般的であるのに対し、日本では pTeX 系エンジンを使う関係で、TeX 処理系と DVI ドライバが別になっているので、これが原因のトラブルが起こりやすいのです。加えて「これが最善の方法」という決定打がないため、それぞれ一長一短がある複数の方式が併存していて、これが初級者の混乱の原因となっています。

この問題に対する究極的な解決法は、日本での TeX の使用が「pdfTeX の日本語版」といえる LuaTeX-ja に収斂されることでしょうが、それにはまだ長い時間がかかります。それまでは、従来の DVI ウェアに関するノウハウが必要な状態が続くでしょう。

タブー①: dvipdfm

って何? dvipdfmx の間違いでしょ。 以上。

その dvipdfm は本当に dvipdfm ですか

どうしても「いや私は dvipdfm を使いたい!」というならそれを止めはしません。だけど、そういう人には、ちょっと確かめてほしいことがあります。

dvipdfm --help を実行してみてください。

This is dvipdfmx-20130405 by the DVIPDFMx project team,
......

もし、こんな風に、This is dvipdfmx から始まるメッセージが出たなら、そう、

あなたが dvipdfm だと思ってるソレは実は dvipdfmx です

これは大事件です。なぜかというと……。

dvipdfm と dvipdfmx は互換じゃない

dvipdfmx はほぼ dvipdfm の上位互換なのですが、画像の読込に関しては決定的な非互換性があります。\includegraphics で画像(EPS 以外)を読み込む場合に必要な事前作業(そう、アレです)が異なるのです。

  • dvipdfm : ebb を起動して .bb ファイルを作成。
  • dvipdfmx : extractbb を起動して .xbb ファイルを作成。

ただし、実際には非互換になるケースはレアなので、間違った方を使っていたとしても(ドライバがソレの方に合っていたなら)大抵の場合には問題は起こりません。だからといって、放っておくと、実際にそのレアケースに当たった場合に頭を抱え込むことになってしまいます。

というわけで、「自分が使ってる dvipdfm が実際には dvipdfmx であった」場合は、dvipdfm 用じゃなくて dvipdfmx 用の作業手順に従いましょう……。

……じゃなくて、素直に、dvipdfmx という名前の dvipdfmx を使いましょう。当然、graphicx のドライバ指定も dvipdfmx にしましょう。(ドライバオプションについては後で触れます。)

\usepackage[dvipdfmx]{graphicx}

(補足)dvipdfm 終了のお知らせ

(2015-12-31補足)

前小節の説明では、「dvipdfm コマンドを実行しても dvipdfmx が起動するなら、それは dvipdfmx と全く同じ動作をする」ことを前提にしていましたが、それは自分の事実誤認による誤りでした(すみません)。正しくは以下のようになります。

  • 2009年~2013年頃の TeX システムにおいて dvipdfm コマンドで起動するのは「dvipdfmx の“dvipdfm 互換モード”」である。
  • これを用いる場合は、“dvipdfm 用の作業手順”に従う必要がある。

しかし、2013年頃にまた状況が変わって、現状は以下のようになっています。

  • 以前と同じく、dvipdfm コマンドで「dvipdfmx の“dvipdfm 互換モード”」が起動する。
  • しかし、graphicx パッケージはもはや dvipdfm をサポートしない。なので、“dvipdfm 用の作業手順”と“dvipdfmx 用の作業手順”のどちらを用いても正常に動作しない場合がある。

つまり、dvipdfm は本当に葬り去られた、ということです。今まで何か理由があって敢えて dvipdfm を使っていた人も、何とかして dvipdfmx に移行する必要があるのです。

詳しくは、以下の記事を参照ください。

タブー②: \includegraphics の bb オプション

dvipdfmx で(dvipdfm は既に葬り去られました)画像を読み込む場合、画像のサイズ(バウンディングボックス)を .xbb ファイルでなくて \includegraphicsbb オプションで指定する、という方法があります。

\includegraphics[bb=0 0 480 360,width=10cm]{banana.jpg}

わざわざ .xbb を作る必要がなくて便利……、確かにそうなのですが、実はこの方法には重大な落とし穴があります。

bb に指定する数値の単位は「ポイント」(bp)である。

もっと端的にいうと。

ピクセル単位ではない。

つまり、例えば JPEG 画像 banana.jpg のサイズを調べて 480×360 ピクセルであるからといって、「bb=0 0 480 360」と指定するのは必ずしも正しくない、ということです。dvipdfm/dvipdfmx において、bb の指定がピクセル単位であったことは過去も含めて一度もありません2

1 bp というのは 1/72 in ≒ 0.3528 mm のこと3で、要するに「物理的な長さ」です。ということは、正しい bb の値を書くには、その画像の「物理的な寸法」を知っている必要があります。PDF 画像はともかく4として、PNG や JPEG 等のビットマップ画像の「物理的な寸法」って何でしょう?

PNG や JPEG の画像形式はビットマップのデータの他に「解像度」(dpi 値)の情報も保持しています(ただしこれはオプションなので無い場合もある)。例えば、480×360 ピクセルの banana.jpg の解像度が 96 dpi であったとします。すると、1 in = 96 px = 72 bp なので、1 px = 0.75 bp という換算になり、これに従うと、banana.jpg の寸法は 360 bp × 270 bp と決まります。

従って、bb オプションの正しい指定は次のようになります5

\includegraphics[bb=0 0 360 270,width=10cm]{banana.jpg}

このように、「解像度」の情報を知れば bb に指定すべき正しい値がわかるのですが、残念ながら、多くの人はそれを調べる手段を知らないものと思います。幸いなことに、TeX を使っているならば、正しい値を調べる極めて簡単な方法があります。それは、「extractbb を実行して .xbb ファイルを得てその中の HiResBoundingBox の値を見る」ことです。

%%Title: ./banana.jpg
%%Creator: extractbb 20130405
%%BoundingBox: 0 0 360 270
%%HiResBoundingBox: 0.000000 0.000000 360.000000 270.000000
%%CreationDate: wed Dec 25 00:10:02 2013

これを見ると、 HiResBoundingBox0.000000 0.000000 360.000000 270.000000 となっているので、これをそのまま bb オプションの値に書けば OK です。

※一般的には、整数値に丸めた BoundingBox よりも小数の HiResBoundingBox の方が正確でより適切です。今の場合は同じ値ですが6

いや、実はもっともっと便利な方法があります!

extractbb で生成した .xbb ファイルをそのまま置いておく と、LaTeX が勝手にその中身を読んでくれます! bb の値を書き写す必要すらありません!

おお、なんと便利な方法なのでしょう……。最初からこれをやっておけばよかったですね…… ;-)

(補足) hiresbb オプション

先ほど、「BoundingBox よりも HiResBoundingBox が望ましい」と書きましたが、graphicx パッケージが .xbb ファイルを読む場合には既定では BoundingBox が使われます。graphicx のオプションに hiresbb を加えると HiResBoundingBox の方を使うようになります。

\usepackage[dvipdfmx,hiresbb]{graphicx}

(補足) 既定の解像度

PNG や JPEG 画像の解像度情報はオプションなので画像ファイルによっては持っていないこともあります。その場合は、dvipdfmx(および extractbb)は解像度として 72 dpi を仮定します7。ちなみに、この時は 1 px = 1 bp となるので、bb に書く値は(偶然)ピクセル数と一致します。

(補足)trim および viewport オプション

\includegraphics のオプションには、「画像の一部分だけを切り出して出力する」ための trim と viewport というオプションがあり、これらの値は bbox と同じ形式の 4 つの数値で指定されます。これらの数値についても非明示時の単位はポイント(bp)と解釈されます(ピクセルではない)。

タブー③: ドライバオプションは dvips だが実際に使ってるのは dvipdfmx

「ドライバオプション」というのは、もちろん、graphicx のパッケージオプションに書くアレです。

\usepackage[dvipdfmx]{graphicx}

大昔ならともかく、今では、graphicx や color の「ドライバオプション」は、用いる DVI ウェア8の名をそのまま指定するのが「正解」です。

すなわち:

  • dvips を使うなら dvips
  • dvipdfmx を使うなら dvipdfmx
  • pdfTeX を使うなら pdftex
  • dviout を使うなら dviout
  • xdvi を使うなら xdvi

(dvipdfm は既に葬り去られました。)
単純明快ですね。

そういうわけで、ドライバオプションと実際の DVI ウェアが一致しないという状態は、少なくともイレギュラーであると認識すべきです。

残念ながら、そういうイレギュラーな指定がどうしても必要な場面(主にドライバのバグ回避のため)は存在しますが、それは要するにバッドノウハウです。

(参考)他のパッケージの事情

graphicx 以外のドライバ依存なパッケージでも、最もメジャーな DVI ウェアである dvips/dvipdfmx/pdfTeX については、最近(5 年以内)では、DVI ウェアとドライバオプションは「一致している」のが正解になっています。つまり、もし dvipdfmx というドライバオプションが存在しないなら、それは「パッケージが dvipdfmx に正式には対応していない」ということです。この場合、「代わりに dvips を指定する」という回避策をとると取り敢えず一部の機能は使えるようになるかも知れません。しかし、その動作は保証されないのはもちろんですし、さらに、「そもそも“間違いの”ドライバが指定されている」ことは想定されていないため、そのせいで思わぬところで不可解な現象が発生するという可能性も覚悟しておく必要があります。

dviout に関しては、本体の開発は細々と続けられているものの、周辺の開発をやろうとする人が皆無であるため、最近のパッケージ(PGF/TikZ、animate、media9 等)についての dviout 対応は全滅という悲惨な状況です。基本的なパッケージである pict2e ですらアウトです。

私は Windows 屋なので、xdvi についてはよく知りません……。

タブー④: dviout(または xdvi)と dvipdfmx の「ドライバ二刀流」

ほとんどの人は、自分がメインに使う DVI ウェアを一つに決めていると思われますが、中には「dviout や xdvi を使って画面上で出力を確認した上で、dvips や dvipdfmx で最終出力(PostScript 文書か PDf 文書)を得る」というアクロバティックな方法を採用している人がいます。この場合、当然ながら、ドライバ指定をどうするかが問題になります。

ただし、dvips との「二刀流」はあまり問題がないようです。というのも graphicx パッケージに関しては dviout も xdvi も比較的 dvips と互換性があるため、ドライバ指定を dvips にすれば済むからです。

問題なのは dvipdfmx との「二刀流」です。昔の dvipdfm は比較的 dvips と互換であったようですが、傾向として dvipdfmx は pdfTeX の機能に近づける方向に発展していて、そのため dvips との互換性は悪くなる一方です。結果的に、dviout/xdvi と dvipdfmx の両方で「正しい出力」を得ようとすることを本当に望むなら、使う DVI ウェアを切り替えるたびに文書中のドライバ指定の方も切り替えるという面倒極まる方法を採るしかなくなっています。

実際に、「dvipdfmx との二刀流」を実践している人を見ると、次のうちのどれかを行っているようです。

  • 実際に、面倒を惜しまず、ドライバ指定を切り替える。
  • ドライバ指定は dvipdfmx として、dviout での完全な表示は諦める。 (それで「確認」になるのかは疑問だが。)
  • なんだかよく解らないバッドノウハウに依拠して苦行を回避する。

何れにしても、少しばかりマゾな感じがします。

どうしてもマゾな道を進みたいというなら止めはしません。でも、他人もマゾであるとは限らないので、dviout/xdvi + dvipdfmx という「マゾな二刀流」を他人に勧めるのは差し控えるのが賢明でしょう。

タブー⑤: ドライバオプションがない

ドライバオプションはオプションなので省略できます。

\usepackage{graphicx}

特に PDF 出力の LaTeX(pdfLaTeX/XeLaTeX/LuaLaTeX)の場合は通常は自動判別されるので、ドライバオプションは省略するのが普通です。では、DVI 出力の LaTeX の場合、省略した場合の既定の値は何でしょう?

答えは:

環境依存です。

つまり、TeX ディストリビューションによって、既定値は異なります。TeX Live を含めて多くの環境では dvips が既定ですが、dvipdfmx が既定になっている環境もあるようです。

DVI 出力で graphicx のドライバオプションを省略している人で、既定値が“何か特定のものである”と思い込んでいた人は、その使用が適切であったかを改めて確認してみてください。特に気を付けてほしいのが、「他人が読むための LaTeX の解説記事を書く」場合です。実際、Web にある解説記事において、「不適切にドライバオプションが省略されている」ケースをよく見かけます。ドライバオプションについて言われなくても解っている中級者を対象としている場合を除いて、たとえ省略が可能なケースであっても、ドライバオプションは明示する方が適切だと思います。

番外編: EPS すべきか PDF すべきか

欧米では、pdfTeX の使用が一般的になり、EPS 形式の画像の使用は非推奨になっています。それに対して、日本では(正確にいえば pTeX 系エンジンを使う場合では)、dvipdfmx を使えば PDF/PNG/JPEG 形式を扱うことができますが、pdfTeX を使う場合と異なり、色々と「弱点」がります。それとは別に、dvips の使用が必須になる場面というのは今でも歴然と存在します。このため、「EPS 形式の使用」が直ちにタブーであるとはいえない状況です。

本記事ではこの話題にはこれ以上踏み込まないこととし、代わりに、次の「2 つの疑問」だけを記しておきます。

  • Distiller を持っていないのに dvips を使っている人に: dvips を使う理由はなんですか?
  • dvipdfmx を使っているのに EPS 画像を使っている人に: EPS 画像を使う理由はなんですか?

もちろん、これらの疑問に対する「正当な理由」はいくらでもあります。問題は、「あなたが正当な理由を持っているのか」ということです。「私は EPS 画像の取り扱いに慣れている」というのも立派な理由になるでしょう。しかし、「これから TeX を始める人は恐らくそうではない」ということも気に留めておくといいでしょう。


  1. 原版はドイツ語で、英語等の 5 言語の版があります。 

  2. bbに指定する値は 112mm のように単位を明示することもできますが、何れにしても、ピクセル単位での指定はできません。 

  3. EPS 時代の慣習を踏んでいるため、TeX のポイント(1 pt = 1/72.27 in)でなく Adobe のポイント(1 bp = 1/72 in)が使われます。 

  4. PDF 画像のサイズは一般的に「物理的な寸法」で現れます。 

  5. ちなみに、この横幅 360 bp は 12.7 cm に等しいので、上の指定の場合、画像は約 78.7 % に縮小されたことになります。 

  6. 360360.000000 に機能の違いはないので、値を書き写す時に無駄なゼロを省いてもかまいません。 

  7. dvipdfm(および ebb)では画像ファイルの持つ情報は無視され、解像度は一律に 100 dpi が仮定されていました。 

  8. pdfTeX などの PDF 出力のエンジンの場合は、便宜的にエンジンを「DVI ウェア」と見なします。