画像形式と取り込み

\includegraphics{plot} と書いたとき、LaTeX に渡しているのはファイル名ではありません。渡しているのは 名前の幹 だけで、graphicx パッケージがそこに .pdf.png.jpg …… と決まった順序で拡張子を継ぎ足しながら探し、最初に見つかったファイルを採用します。同じ原稿が pdfLaTeX でも LuaLaTeX でも dvipdfmx でも通るのはこの設計のおかげで、「PNG を作り直したのに図が変わらない」という事故が起きるのもまた同じ設計のせいです。このページでは、画像取り込みの中心である \includegraphics のオプション、\graphicspath による探索パス、エンジンごとに読める画像形式、そして「File not found」と言われたときの読み解き方を扱います。

graphicx と \includegraphics — 拡張子を書かない理由

画像取り込みは標準の graphicx パッケージが担当し、\usepackage{graphicx} を宣言してから \includegraphics[オプション]{名前} と書きます。ここで拡張子を省くのが定石で、その理由は graphicx の内部を見ると一目瞭然です。pdfTeX 用のドライバファイル pdftex.def には、試す拡張子の並びが .pdf, .png, .jpg, .mps, .jpeg, .jbig2, .jb2 という順で書かれています。つまり plot.pdfplot.png の両方がフォルダにあれば、必ず PDF が勝ちます。グラフを PNG に書き出し直しても図が変わらないときは、たいてい古い plot.pdf が同じフォルダに残っています。逆にいえば、拡張子を書かないからこそ、後日 PNG を PDF に差し替えるだけで原稿を一文字も直さずに済むわけです。graphicx はより古い graphics パッケージの拡張版で、オプションをキー=値の形でまとめて渡せるのが違いです。どちらも LaTeX 標準の latex-graphics バンドルに含まれ、別途インストールは要りません。

document.tex
\documentclass{article}
\usepackage{graphicx}
\begin{document}
% no extension: graphicx tries .pdf, .png, .jpg ... in that order
\includegraphics[width=0.6\textwidth]{plot}
\end{document}

拡張子を書いてしまうと、この自動選択が止まるだけでなく、エラーの文面まで変わります。名前だけを渡した \includegraphics{plot} が空振りすると、探索を担当している LaTeX 本体が ! LaTeX Error: File 'plot' not found. と言います。いっぽう \includegraphics{plot.png} と拡張子まで書いて空振りすると、今度はドライバが答えて ! Package pdftex.def Error: File 'plot.png' not found: using draft setting. になります。前者は「どの拡張子でも見つからなかった」、後者は「その一枚が無い」という別々の意味で、どちらが出たかで探すべき場所が変わります。なお TeX Live に含まれる mwe パッケージは example-image.pdfTeX のツリーそのもの に置くので、どのフォルダからでも \includegraphics{example-image} が通ります。質問サイトの最小例に必ずこの名前が出てくるのはそのためです。

大きさの指定 — width, height, scale, keepaspectratio

実務では大きさの指定がほぼ必須で、しかも width=0.8\textwidth のように版面基準の相対値 で書くのが定石です。8cm のような絶対値で書くと、二段組に切り替えたときも用紙サイズを変えたときも図だけが取り残されます。\textwidth は本文の幅、\linewidth は「いま組んでいる行の幅」で、minipagesubfigure の中では後者が箱の幅に縮みます。だから箱の中では width=\linewidth と書いておけば、箱の幅をあとから変えても図が自動で追随します。scale= は画像本来の寸法に対する倍率で、その寸法自体に意味があるときに向きますが、版面の幅とは無関係なのではみ出しやすく、ふつうは width= のほうが安全です。

width=height= を両方書くと、graphicx は素直に両方に従うので 縦横比が壊れて画像が歪みます。これを防ぐのが keepaspectratio で、付けると「指定した幅と高さで作る枠に収まる範囲で、比を保ったまま最大化する」動きに変わります。写真を規定サイズの枠に流し込むときはほぼ必ず併記します。もう一つ、確認用に覚えておくと便利なのが draft オプションです。画像を実際には読み込まず、寸法どおりの枠と中身のファイル名だけを組むので、図が何百枚もある文書の試し組みが劇的に速くなります。\usepackage[draft]{graphicx} と書けば文書全体に効きます。

回転と切り抜き — angle, trim, clip, viewport

angle=反時計回り の回転角を度で受け取ります。angle=90 は左に 90 度、横長のグラフを縦置きのページに載せるときの定番です。ここで注意したいのは angle=width= を書く 順序 で、graphicx はキーを書かれた順に適用します。[angle=90,width=6cm] は「回してから幅 6cm に合わせる」、[width=6cm,angle=90] は「幅 6cm にしてから回す」で、結果の寸法が違います。回転の中心は既定で画像の左下ですが、origin=c で中央に、origin=tr で右上に移せます。

画像の縁を切り落とすには trim=clip を組み合わせます。trim左・下・右・上 の順に四つの値を取り、この順番は原点が左下にある PostScript の座標系に従っているので、上下左右の直感とは合いません。既定の単位は bp(ビッグポイント、1 インチの 72 分の 1) です。そして clip を必ず添えてください。書き忘れると、切り落としたはずの部分が消えずに周囲の本文へはみ出して重なります。負の値を渡すと逆に余白が足され、図の周りに空きを作れます。切り抜く範囲を「四辺からいくら削るか」ではなく絶対座標の矩形で指定したいときは viewport= を使い、こちらも clip と組み合わせます。

latex
% half the text width
\includegraphics[width=0.5\textwidth]{photo}

% fit inside 8cm x 5cm without distortion
\includegraphics[width=8cm,height=5cm,keepaspectratio]{photo}

% rotate a quarter turn to the left, then scale the result
\includegraphics[angle=90,width=6cm]{diagram}

% shave 20bp left, 20bp bottom, 30bp right, 10bp top -- clip is mandatory
\includegraphics[trim=20 20 30 10,clip,width=6cm]{scan}

% page 3 of a multi-page PDF
\includegraphics[page=3,width=\linewidth]{report}
オプション働き
width=出力上の幅。0.8\textwidth のような相対値が定石
height=出力上の高さ。width= と併用するなら keepaspectratio を添える
scale=画像本来の寸法に対する倍率(scale=0.5 で半分)
angle=反時計回りの回転角(度)。width= との記述順で結果が変わる
origin=回転の中心。既定は左下、c で中央、tr で右上
keepaspectratio幅と高さが作る枠に、比を保ったまま最大で収める
trim= ... clip左・下・右・上を削る。単位は既定で bp、clip は必須
viewport= ... clip絶対座標の矩形で切り抜き範囲を指定する。clip と併用
page=複数ページ PDF の何ページ目を取り込むかを選ぶ(既定は 1 ページ目)
draft画像を読まず、寸法どおりの枠とファイル名だけを組む。試し組み用

\graphicspath で画像フォルダを指す

画像を別フォルダにまとめているなら、\graphicspath で探索パスを足します。ディレクトリ名は一つずつ波括弧で囲み(一つしかなくても囲む)、末尾に必ずスラッシュ / を付けます(Windows でも /)。 探索の順序は実験で確かめられます。カレントディレクトリに同名の画像があるとそれが最優先で使われ、無ければ \graphicspath書いた順 で先に見つかったものが採られます。だから \graphicspath{{figures/}{old-figures/}} と並べておけば、figures/ の新しい版が自動的に古い版を隠し、まだ差し替えていない図だけが old-figures/ から拾われる、という運用ができます。空白を含むパスは {"my figures/"} のように引用符でくくってください。試す拡張子の並びそのものを変えたいときは \DeclareGraphicsExtensions を使います。

latex
\usepackage{graphicx}
% braces around each directory, trailing slash on each, searched in this order
\graphicspath{ {figures/} {../shared-figures/} }

% narrow or reorder the list of extensions graphicx will try
\DeclareGraphicsExtensions{.pdf,.png,.jpg}

PDF か PNG か — ベクタとラスタの選び分け

判断の基準は一つで、線と文字でできた図はベクタ、連続階調の画像はラスタ です。ベクタ画像(PDF・EPS・SVG)は点と線と曲線を座標として記述するので、どこまで拡大しても輪郭が計算し直され、印刷解像度に一切依存しません。グラフ・回路図・数式入りの図面はこちらです。ラスタ画像(PNG・JPEG)は色のついた画素を格子に並べたもので、拡大すれば画素が大きくなるだけです。写真とスクリーンショットはこちらで、印刷に出すなら 300 dpi 以上の元データを用意します。写真をベクタ化しても得るものはなく、ファイルだけが肥大します。TikZ や pgfplots のように LaTeX の中で図を 生成 する場合、出力は最初からベクタです。

ラスタの中では、JPEG は写真、PNG はそれ以外 と覚えておけば足ります。JPEG は非可逆圧縮で写真の階調に強い代わりに、線画や文字の縁にモスキートノイズと呼ばれるにじみが出ます。スクリーンショットを JPEG で保存すると文字の周りが汚れるのはこのためです。PNG は可逆圧縮で透明度も扱え、単色面の多い図やスクリーンショットに向きます。なお SVG はどのエンジンも直接は読めませんsvg パッケージを使えば \includesvg{file} と書けますが、これは裏で Inkscape のコマンドラインを呼び出して PDF(DVI 出力時は EPS)に変換し、SVG 内の文字は別ファイルに書き出して LaTeX 側で組み直すという仕掛けです。Inkscape のインストールと --shell-escape 付きのコンパイルが要ります。安定を取るなら、Inkscape などで先に PDF へ書き出しておくのが確実です。逆に TeX の出力を SVG にしたい場合は dvisvgm が使えます。

どのエンジンがどの形式を読むか — EPS は本当に読めないのか

受け付ける形式を決めているのはエンジンではなく、その先の ドライバファイル です。graphics.cfg が起動時にエンジンを見分けて、pdfTeX なら pdftex.def、XeTeX なら xetex.def、DVI 出力なら dvips.def を読み込み、そのファイルに書かれた拡張子リストがそのままサポート形式になります。ここから、よく語られる話に二つの訂正が要ります。ひとつ、XeLaTeX と dvipdfmx は EPS も PS も直接扱えますxetex.defdvipdfmx.def の拡張子リストには .eps.ps が、さらに .ai.bmp.jp2 まで並んでいます。ふたつ、pdfLaTeX と LuaLaTeX も、実質的には EPS を読めます

コンパイル経路ドライバ試される拡張子(この順)
pdflatexpdftex.def.pdf .png .jpg .mps .jpeg .jbig2 .jb2。シェルエスケープが有効なら末尾に .eps が加わる
lualatexluatex.defpdftex.def と同一の並び。.eps の扱いも同じ
xelatexxetex.def.pdf .ai .png .jpg .jpeg .jp2 .jpf .bmp .ps .eps .mps — EPS も PS も直接
platex + dvipdfmxdvipdfmx.defxetex.def と同じ並び。寸法は .xbb 補助ファイルから採ることがある
latex + dvipsdvips.def.eps .ps .eps.gz .ps.gz .eps.Z .mps のみ。PDF も PNG も JPEG も入らない

pdfLaTeX が EPS を通す仕組みは pdftex.def の中に書かれています。\begin{document} の時点でシェルエスケープが有効なら、このファイルは自分で .eps を拡張子リストに追加し、epstopdf-base を読み込みます。しかも TeX Live の既定である制限付きシェルエスケープで十分 で、--shell-escape は要りません。制限モードでは repstopdf という安全側の版が呼ばれ、--shell-escape を付けたときだけ epstopdf 本体に切り替わります。変換結果はソースの隣に myfig-eps-converted-to.pdf という名前で置かれます。ただし pdftex.def 自身が注意書きを添えていて、EPS ではなく PDF のほうが原本のときはこの自動変換が 間違った結果を生む ことがあります。止めたいときは \documentclass よりも前に \newcommand{\DoNotLoadEpstopdf}{} と書きます。

latex
% EPS under pdflatex already works; this line only makes it explicit
\usepackage{epstopdf}

% ... and this, placed BEFORE \documentclass, switches the conversion off
% \newcommand{\DoNotLoadEpstopdf}{}

% pLaTeX / upLaTeX: the driver cannot be detected, so name it
% \usepackage[dvipdfmx]{graphicx}

この自動変換に頼りすぎない理由もあります。制限シェルエスケープを切って pdflatex -no-shell-escape で走らせると .eps は拡張子リストに追加されないので、myfig.eps が目の前にあっても ! LaTeX Error: File 'myfig' not found. になります。さらに厄介なのは拡張子まで書いた場合で、\includegraphics{myfig.eps}エラーも警告も出さずに、画像の代わりにファイル名を印字した枠を組んでしまいます。共同執筆やビルドサーバーで -no-shell-escape が使われる現場では、EPS を事前に PDF へ変換して版管理に入れておくのが安全です。日本語で使う pLaTeX / upLaTeX はドライバを自動判別できないので、\usepackage[dvipdfmx]{graphicx} と明示してください。PNG・JPEG・PDF の寸法情報が要る場合は extractbb.xbb を作ります。

「File not found」と言われたとき

画像まわりのエラーは、文面がそのまま原因を指しています。四つ覚えておけば、たいていの事故はその場で片づきます。! LaTeX Error: File 'plot' not found. は「拡張子リストのどれでも見つからない」。綴りか \graphicspath か、あるいは EPS しか無いのにシェルエスケープが切られている場合です。! Package pdftex.def Error: File 'plot.png' not found: using draft setting. は「その一枚が無い」。! LaTeX Error: Unknown graphics extension: .tiff. は「ファイルはあるが、この経路はその形式を知らない」で、TIFF や WebP をそのまま渡すとこれになります。PNG か PDF に変換してください。

四つ目は少し性格が違います。! LaTeX Error: Cannot determine size of graphic in plot.png (no BoundingBox). は「ファイルは読めたが、寸法がわからない」というエラーです。BoundingBox 行を欠いた EPS を渡したときにも出ますが、実務でこれに出会う圧倒的多数の理由は pdflatex のつもりで latex を起動していること です。latex は DVI を出す経路なので dvips.def が読み込まれ、PNG や JPEG のバイト列を寸法として解釈できません。図が急にすべて壊れたら、まずコンパイル命令を疑ってください。

  • EPS の BoundingBox: 行が無い・値が誤っていると寸法が決まらない。ps2epsepstool で書き直す。
  • 複数ページ PDF: 既定では 1 ページ目だけ。page= でページを選ぶ。文書を丸ごと差し込むなら pdfpages パッケージ。
  • PDF の余白: 図の PDF に余白が多いと図が小さく見える。pdfcrop で余白を切り詰めてから取り込む。
  • ファイル名の空白・ピリオド: my plot.tar.gz のような名前は拡張子の切り出しに失敗しやすい。英数字とハイフン、アンダースコアに留める。
  • 拡張子の書きすぎ: 拡張子を明示すると形式の差し替えが効かなくなる。原則は拡張子なし。

最後に、\includegraphics は画像を その場に置くだけ で、番号もキャプションも付けない、という点を確認しておきます。論文で「図 3 を参照」と書くには、画像を figure 環境に入れて \caption\label を添えます。そこから先——[htbp] の指定でどこに出るか、キャプションをどう飾るか、(a)(b) に分けるにはどうするか——は、このページの姉妹ページが引き受けます。