Skip to content

Instantly share code, notes, and snippets.

@yarakos95
Last active July 17, 2024 05:10
Show Gist options
  • Save yarakos95/9e17e060abc98073aaffe3ba27f409dd to your computer and use it in GitHub Desktop.
Save yarakos95/9e17e060abc98073aaffe3ba27f409dd to your computer and use it in GitHub Desktop.
TeX から画像を生成したい

TeX から画像を生成したい

TeX からPDF を作成して画像を生成したい.画像はラスターのPNG(Portable Network Graphics) または,ベクターのSGV(Scalable Vector Graphics) を生成したい.

通常通りにPDF を作成した場合,余白が多く作成されてしまう.この余白を作らない,あるいは取り除くように作成したい.

また,PDF からこれらの画像を生成するもっとも安直な方法は,以下のようなコンバータを利用して変換することであるが,いちいちアクセスしたりするのは面倒である.出来るだけローカルで完成させたい.

実は,TeX Live に同封されたコマンドラインツールを利用してローカルで完成させることが出来る.

今回利用するツールは以下の通りになる. pdftocairo やpdfimages はPoppler というPDF ライブラリの1つとなっている.

  • standalone クラス
  • preview パッケージ
  • pdfcrop
  • pdftocairo
  • (pdfimages)

また,これをVSCode で利用できるようにすることを最終目標としたい.

Summary

書き終えてみたものの,かなり文章量が多くなった. 目的とタイプセット方法,利用するパッケージなどが明らかな方が目次を見るよりも明瞭な気がしてきたので表にしてみた.

タイプセットによってもTeX の作成方法が異なるので注意が必要. ただしPDF から画像に変換する方法はいずれのタイプセット方法であっても同じになる.

画像にしたいコンテンツ\ タイプセット (u)pLaTeX+dvipdfmx LuaLaTeX
行内数式 standalone standalone, preview
別行立て数式 トリミング preview
standalone standalone, preview
キャプション付き表 トリミング preview
TikZ (standalone), トリミング standalone

"トリミング" としている箇所はA4 などで通常通りに作成してから,pdfcrop でトリミングすることを指している.

(u)pLaTeX+dvipdfmx の注意点 : まったく利用できないわけではないが,いくつかの点で期待通りの結果を得られない場合がある.特定のフォント等で使用したい場合を除いてはLuaLaTeX を利用した方が良いだろう. あるいは,トリミングすることを主軸に考えた方が有用だろう.

Table of Contents

TeX をPDF に

TeX からPDF に変換する方法はいくつもある.どの方法を採っていても問題ない.(と言いつつ,記事中では度々dvipdfmx に対する注意を入れている) しかし,画像に変換する場合はA4 サイズなどで出力したPDF には余白が出来てしまい不格好になる.これを解消したい.

これには以下の2つの方法がある.

  • 余白のないPDF を作成する(standalone クラス,preview パッケージ)
  • 余白部分をトリミングする

これらを順に見ていきたい.

■ standalone クラス

standalone | CTAN

standalone バンドル(クラスとパッケージの両方がある) はdocmute やsubfiles と同じようにファイルを分割することでそれぞれのタイプセットを軽くするためのものになっている.

ただし,docmute やsubfiles と大きく異なる点として,standalone が扱うものは1つのページそのものではなく,ドキュメントを構成する要素のみを作成する(表やTikZ による描画を余白がないPDFにする) ことが出来る点にある.

これを利用して,表やTikZ による描画を余白なしにPDF を作成することを考えたい. 本来はここで作成した表などを挿入したいドキュメントに戻して作成することになるが,ここでは単に画像を作成したいだけなのでドキュメントに挿入する方法は述べない.

cf. The standalone pakcage, §5 Usage of the standalone class

基本的な使い方は以下のようになる.

\documentclass{standalone}
%
% some packages
%
\begin{document}
  % tabular, formular, TikZ ...etc
\end{document}

複数のオプションを指定する場合には, で区切る.

▽ dvipdfmx の利用

タイプセットには(u)pLaTeX+dvipdfmx を利用しても問題ないようだ. ただし,DVI に依存するパッケージを利用する際にはdvipdfmx をグローバルオプションとして読み込ませておく必要がある.(パッケージのドキュメントにはdvipdfmx への言及はなされていないが,実行することは可能となっている)

standalone クラスは dvipdfmx でも使えるような気がする - GitHub

以下のようにドキュメントクラスを読み込もう.

\documentclass[dvipdfmx]{standalone}

ただし,複数ページに渡る場合には,1ページ目のサイズが2ページ目以降にも反映されるという問題が生じてしまう. 特にこだわりがなければLuaLaTeX を利用するか,単数ページのみを作成するようにしよう.

▽ クラスの変更

基本的なドキュメントクラスはarticle となっている. これを変更することも可能である.class オプションを利用しよう.

: jsarticle に変更することを考える.このときのタイプセットはupLaTeX+dvipdfmx で行う.

\documentclass[dvipdfmx,uplatex,class=jsarticle]{standalone}

class で読み込むクラスに必要なオプションはclass=hoge より前に挿入する必要がある.

▽ 余白を作る

余白がまったくないので,PDF を生成するとギリギリに出力される. 画像として利用する場合には少しだけ余白があった方が良いだろう.(また,出力すると少し見切れていることがある) border オプションを利用すれば良い.

\documentclass[border=1mm]{standalone}

以下のいずれかのようにしても良い.

border=<length (all sides)>
border={<length (left/right)> <length (bottom/top)>}
border={<length (left)> <length (bottom)> <length (right)> <length (top)>}

ちなみにmargin でもborder と同じ結果を得る.

▽ 改ページ

standalone ではコンテンツ全体が1つのブロックであり,1つのページに表示されるべきであると想定しているため,そのままでは複数ページの作成は出来ない. multi オプションを利用しよう.

このオプションは1つのページにしたいコンテンツを任意の環境に挿入することで得られる. 任意の環境名は,既存の環境名でも自作の環境名でも問わない.

\documentclass[multi=hoge]{standalone}
% some packages
\begin{document}
%
% Created here as a new page
\begin{hoge}
  % content
\end{hoge}
%
% Created here as a new page
\begin{hoge}
  % content
\end{hoge}
% more hoge environments ...
\end{document}

(u)pLaTeX+dvipdfmx を利用する場合は,1ページ目のサイズが2ページ目以降にも反映されるため注意が必要.

▽ 数式

equation 環境やalign 環境などの別行立ての数式環境を利用することが出来ない. したがって,利用できるのは行内環境のみになる.

そのため,以下のように$ で囲み\displaystyle でディスプレイスタイルに変更する必要がある.

$\displaystyle
  % Equation
$

あるいは,multi オプションを利用して複数の数式を同時に作成したい場合にはmath 環境を利用すると良いだろう.これはLaTeX 標準の行内数式環境である. また,amsmath を読み込んでいても問題ない.

\documentclass[multi=math]{standalone}
% It doesn't matter if you load amsmath
\begin{document}
%
% Created here as a new page
\begin{math}\displaystyle
  % Equation
\end{math}
%
% Created here as a new page
\begin{math}\displaystyle
  % Equation
\end{math}
% more math environments ...
\end{document}

しかし,行内数式しか用いることが出来ないために以下のような数式を生成することは出来ない.

  • align 環境などの& で関係演算子などを揃えた数式(行列などは除く)
  • 式番号付きの数式

したがって,これらのような数式を作りたい場合には次のpreview パッケージを利用するかトリミングすることを考えると良いだろう.

▽ 表

表を作成する場合にはtabular 環境を利用すれば良い. ここでtable 環境を利用する必要はない.(というよりも利用できない)

%
% DO NOT surround in table environment
%
\begin{tabular}
  % table contents
\end{tabular}

preview パッケージではtable 環境を利用することが出来るようになる.利用したい場合には参照してほしい.

▽ TikZ

TikZ を利用する場合はtikz オプションを利用する.このオプションを有効にするとき,multi=tikzpicture,varwidth=false と同じになる.

このオプションによってTikZ が自動的に読み込まれ,tikzpicture 環境を利用することが出来るようになる. また,複数のtikzpicture 環境を用いるとページを変えたPDF を得ることが出来る.

\documentclass[tikz]{standalone}
% some packages
\begin{document}
%
% Each tikzpicture environment switches pages
%
% first TikZ
\begin{tikzpicture}
  % tikz
\end{tikzpicture}
%
% second TikZ
\begin{tikzpicture}
  % tikz
\end{tikzpicture}
% more tikzpictures ...
\end{document}

ただし,(u)pLaTeX+dvipdfmx を利用する場合には少し勝手が異なるようである.

standaloneクラス - Qiita

tikzpicture 環境が1つのみであればtikz オプションの利用で問題ないが,複数のtikzpicture 環境を利用する場合には正常にオプションが機能しないようだ.

したがって,multi=tikzpicture を有効にして\usepackage{tikz} とすれば良い.

\documentclass[multi=tikzpicture,dvipdfmx]{standalone}
\usepackage{tikz}
% some packages
\begin{document}
  % tikzpicture environments
\end{document}

しかし,この場合であっても1ページ目のサイズが2ページ目以降にも反映されるため注意が必要.

やはり,LuaLaTeX を利用すればすべて解決!

■ preview パッケージ

preview | CTAN

preview パッケージを利用するとstandalone で不可能だった番号付き数式やtabel 環境を利用することが出来る. ただし,このパッケージはdvipdfmx を利用して上手く余白を消すことが出来ない.

dvipdfmx で preview パッケージする件について - マクロツイーター

上の記事ではdvipdfmx であっても利用できるように解決している.ただし,TeX Live のみでは解決しないことに注意したい.


以下ではLuaLaTeX でタイプセットすることを前提にpreview パッケージを利用することを想定する.

preview パッケージは以下のように読み込む.activetightpage オプションは有効にしておく. 基本的にはpreview 環境内のコンテンツを余白のない1ページとして出力する.

\usepackage{article}
\usepackage[active,tightpage]{preview}
% some packages
\begin{document}
%
% Created here as a new page
\begin{preview}
  % tabular, formular, TikZ ...etc
\end{preview}
%
% Created here as a new page
\begin{preview}
  % tabular, formular, TikZ ...etc
\end{preview}
% more preview environments
\end{document}

このパッケージでは幅が最大のコンテンツにしたがって他のコンテンツの幅が決定されるようだ.(どこかに最大幅はあるようだ) また,この大きさはドキュメントクラスで指定するペーパーサイズにも依存するようである.

余白はほとんどいじる必要はないと思われる.しかし,必要であればgeometry パッケージを利用して行えば良い.

▽ 番号付きの数式

オプションからdisplaymath またはtextmath とすれば,別行立て数式,行内数式がページを変えて出力される.

これらの数式はpreview 環境で囲う必要はない.(オプションを指定しない場合にはpreview 環境で囲う必要がある)

\documentclass{article}
\usepackage{amsmath}
% It doesn't matter if you load amsmath
% Loading order; amsmath --> preview with `displaymath` option
\usepackage[active,tightpage,displaymath,textmath]{preview}
\begin{document}
%
% Created here as a new page
$ \alpha $
%
% Created here as a new page
\beign{equation}
  % Numbered equation
\end{equation}
%
% Created here as a new page
\beign{align}
  % Numbered equaitons
\end{align}
% more mathematics environments ...
\end{document}

これで出力すると式番号が付与されている.

amsmath から提供されている* 付きの環境では式番号は付与されない.ただし,式番号を付与しない場合には右側が切り取られてしまう.

displaymath オプションを使用せずにpreview 環境を利用すると解消される.ただし,この場合ではalign 環境を使用した数式の上側に余計は空白が作られてしまうようだ. あるいは,mathtools のshowonlyrefs オプションを用いれば式番号なしでも右幅を切り取られない結果を得ることが出来る.

\documentclass{article}
\usepackage{amsmath}
\usepackage{mathtools}
\usepackage[active,tightpage,displaymath,textmath]{preview}
\mathtoolsset{showonlyrefs}
\begin{document}
%
\begin{equation}
  % single equation
\end{equation}
%
\begin{align}
  % multi equations
\end{align}
\end{document}

\lable\noeqref で式番号を表示させることが出来そうだったが上手くいかなかった.(この方法でやっていると安定して欲しい結果を得られなかった.)

▽ table 環境

standalone ではtabel 環境を利用できなかったが,preview パッケージでは利用することが出来る. floats オプションを利用する.このとき,preview 環境で囲う必要はない.

\documentclass{article}
\usepackage[active,tightpage,float]{preview}
% some packages
\begin{document}
\begin{table}
  \centering
  \caption{CAPTION}
  \begin{tabular}
    % table contents
  \end{tabular}
\end{table}
\end{document}

キャプションの番号も機能している.ただし,レイアウトが少し残念な形になるように思われる.(テスト方法が悪かったか?)

▽ TikZ

preview パッケージでももちろんTikZ で描画したものを出力することが出来る.

\documentclass{article}
\usepackage[active,tightpage]{preview}
\usepackage{tikz}
\begin{document}
%
% Created here as a new page
\begin{preview}
  \begin{tikzpicture}
    % tikz ...
  \end{tikzpicture}
\end{preview}
%
% Created here as a new page
\begin{preview}
  \begin{tikzpicture}
    % tikz ...
  \end{tikzpicture}
\end{preview}
% more preview environment with tikzpicture
\end{document}

ただし,standalone と異なる点は,以下の2つある.

  • 余白が勝手に少しだけ作成される
  • 円形などを描画するとそれを囲う四角形で出力される

■ トリミングする

jsarticle などで作成してA4 サイズのPDF を作成して余白部分をトリミングで取り除きたい.

pdfcrop - TeX Wiki

pdfcrop を利用する.これはTeX Live にも収録されている. 詳しい使い方は$ texdoc pdfcrop とするか$ pdfcrop --help とすれば見ることが出来る.

コマンドラインでは以下のように利用する.

$ pdfcrop test.pdf

test-crop.pdf が出力される.同じファイル名で出力したい場合はtest.pdf を続けて追加する.

これにはページ番号も加味してトリミングされるため,ページ番号は消去しておいた方が良い. TeX ファイルでページ番号が出力されないように以下をプリアンブルに追加する.

\pagestyle{empty}

また,数式に式番号を付与したい場合,用紙サイズをB5 にするなどA4 より少し小さくすると良い感じの大きさになる(気がする)

▽ 余白を残す

--margings オプションでドキュメント内の構造から左,上,右,下の順で余白(単位: bp) を設定することが出来る. これらの数値が2つの場合は左右,上下で等しい値,1つの場合は上下左右で等しい値としてみなされる.

$ pdfcrop --margins "10 5" test.pdf

左右に10bp,上下に5bp の余白が作られる.


任意PDF のトリミング : もしも,コマンドラインで任意のPDF をトリミングしたい場合には余白をマイナスにして欲しいところを逐次確認しながら切り出すことになる. 凄く面倒くさい.

pdfcropで任意の範囲を切り抜く - Qiita

これに関してはオンライン上のサービスを利用した方が懸命である.PDF を見ながら切り取ることが出来る.

PDFトリミング - オンライン無料でPDFページを切り取る - HiPDF

また,PDF に含まれている画像を出したい場合であれば,トリミングするよりも画像抽出を考えた方が懸命である. Poppler ライブラリのpdfimages を利用して抽出しよう.

Poppler:pdfimages の使い方 | PDF

▽ VSCode でトリミング

これをVSCode のLaTeX Workshop でのrecipe から使えるようにしたい. settings.json で以下のようにする.(TeX をタイプセットするtool やrecipe は含めていないので注意.適宜挿入してほしい.)

    "latex-workshop.latex.recipes": [
      // Recipes for compiling TeX to PDF
      // ... ...
      {
        "name": "Trimming PDF",
        "tools": [
          "pdftrimming",
        ]
      },
    ],
    "latex-workshop.latex.tools": [
      // Tools for compiling TeX to PDF
      // ... ...
      {// Trimming PDF
        "name": "pdftrimming",
        "command": "pdfcrop",
        "args": [
          "--margins",
          "10 5",
          "%DOC%.pdf",
          "%DOC%.pdf",
        ]
      },
    ],

デフォルトでは"-crop" がファイル名に加わってしまうので,同じファイル名にするために"%DOC%.pdf" を加えている.

PDF を画像に

Poppler

pdftocairo を利用する.これはPoppler というPDF ライブラリの一つになる.TeX Live にも収録されている. 詳しい使い方は$ texdoc pdftocairo とするか$ pdftocairo --help とすれば見ることが出来る.

PNG に変換

コマンドラインでは以下のように利用する.PNG に変換してみる.

$ pdftocairo -png -r 300 test.pdf

デフォルトでは縦横の1インチ当たりのピクセル数(PPI) が150 となっている. これは比較的荒いように感じる.そのため,オプション-r に続けてPPI値 を与えれば良い.上の例では300PPI (デフォルトの倍) としている.

また,PNG の背景は白になっているが,透明にしたい場合には-transp オプションを付与する.

$ pdftocairo -png -r 300 -transp test.pdf

SVG に変換

SVG に変換する場合は以下のようにする.

$ pdftocairo -svg test.pdf

ただし,複数ページのPDF をSVG に変換する場合,SVG がうまく表示されなくなる.(SVG2.0が関係するらしい) 単数ページのみで利用するようにしよう.

複数ページのPDF をSVG に変換するにはページを指定しながら変換すると良いだろう. オプションで-f から-l までのページを指定することが出来る.3ページ目を変換するには以下のようにする.

$ pdftocairo -svg -f 3 -l 3 test.pdf

■ VSCode で変換

先ほどと同様にこれをVSCode のLaTeX Workshop でのrecipe から使えるようにしたい. settings.json で以下のようにする.(TeX をタイプセットするtool やrecipe は含めていないので注意.適宜挿入してほしい.)

    "latex-workshop.latex.recipes": [
      // Recipes for compiling TeX to PDF
      // ... ...
      {
        "name": "Convert PDF to PNG",
        "tools": [
          "pdf2png",
        ]
      },
    ],
    "latex-workshop.latex.tools": [
      // Tools for compiling TeX to PDF
      // ... ...
      {// Convert PDF to PNG
        "name": "pdf2png",
        "command": "pdftocairo",
        "args": [
          "-png",
          "-r",
          "300",
          // "-transp",// If use a transparent page color instead of white
          // "-singlefile",// Only convert first page and Remove file number
          "%DOC%.pdf",
          // "%DOC%-image",
        ]
      },
      {// Convert PDF to SVG
        "name": "pdf2svg",
        "command": "pdftocairo",
        "args": [
          "-svg",
          "-f",
          "1",
          "-l",
          "1",
          "%DOC%.pdf",
          // "%DOC%-image.svg",
        ]
      },
    ],

注意 : PPI を変更するオプション引数は-r 300 などとするが,なぜか分けていないと上手く実行できなかった.別行に分けておこう. また,SVG では複数ページのPDF を変換しようとすると上手く表示できなくなってしまうので,1ページ目のみを変換するようにしている.2ページ目以降は変換されない.

▽ ファイル名

上の設定でのtest.tex -> test.pdf -> PNG とすることを考える.

そのままで行うとtest-1.png となる.また,複数ページのPDF であればtest-1.png, test-2.png, ... と数字が増えていく.

-singlefile オプションを有効にするとtest.png となる.ただし,PDF が複数ページの場合,1ページ目のみしか生成されないことに注意が必要.

"%DOC%-image" を有効にすると,test.pdf をtest-image-1.png とすることが出来る.-image の部分は任意に変更しても良いだろう.(ただし,SVG では.svg まで含める必要があるようだ)

VSCode でTeX からPNG まで

トリミングと変換のためのrecipes とtools をまとめておこう.

settings.json まとめ (折りたたみ)

ptex2pdf を利用したupLaTeX+dvipdfmx, LuaLaTeX によるのタイプセットを含めたsettings.json を明らかにしておきたい.

    "latex-workshop.latex.recipes": [
        {
          "name": "ptex2pdf: 1 time Build",
          "tools": ["uptex2pdf"]
        },
        {
          "name": "LuaLaTeX: 1 time Build",
          "tools": ["lualatex"]
        },
        {
          "name": "Trimming PDF",
          "tools": ["pdftrimming"]
        },
        {
          "name": "Convert PDF to PNG",
          "tools": ["pdf2png"]
        },
        {
          "name": "Convert PDF to SVG",
          "tools": ["pdf2svg"]
        },
        // {
        //   "name": "ptex2pdf: TeX to PNG",
        //   "tools": [
        //     "uptex2pdf",
        //     "pdftrimming",
        //     "pdf2png"
        //   ]
        // },
        // {
        //   "name": "LuaLaTeX: TeX to PNG",
        //   "tools": [
        //     "lualatex",
        //     "pdftrimming",
        //     "pdf2png"
        //   ]
        // },
        // {
        //   "name": "ptex2pdf: TeX to SVG",
        //   "tools": [
        //     "uptex2pdf",
        //     "pdftrimming",
        //     "pdf2svg"
        //   ]
        // },
        // {
        //   "name": "LuaLaTeX: TeX to SVG",
        //   "tools": [
        //     "lualatex",
        //     "pdftrimming",
        //     "pdf2svg"
        //   ]
        // },
      ],
      "latex-workshop.latex.tools": [
        // Tools for compiling TeX to PDF
        // ... ...
        {// ptex2pdf
          "name": "uptex2pdf",
          "command": "ptex2pdf",
          "args": [
            "-u",
            "-l",
            "-ot",
            "-kanji=utf8",
            "-interaction=nonstopmode",
            "-file-line-error",
            "%DOC%",
          ]
        },
        {// LuaLaTeX
          "name": "lualatex",
          "command": "lualatex",
          "args": [
            "-interaction=nonstopmode",
            "-file-line-error",
            "%DOC%",
          ]
        },
        {// Trimming PDF
          "name": "pdftrimming",
          "command": "pdfcrop",
          "args": [
            "--margins",
            "10 5",
            "%DOC%.pdf",
            "%DOC%.pdf",
          ]
        },
        {// Convert PDF to PNG
          "name": "pdf2png",
          "command": "pdftocairo",
          "args": [
            "-png",
            "-r",
            "300",
            // "-transp",// If use a transparent page color instead of white
            // "-singlefile",// Only convert first page and Remove file number
            "%DOC%.pdf",
            "%DOC%-image",
          ]
        },
        {// Convert PDF to SVG
          "name": "pdf2svg",
          "command": "pdftocairo",
          "args": [
            "-svg",
            "-f",
            "1",
            "-l",
            "1",
            "%DOC%.pdf",
            "%DOC%-image.svg",
          ]
        },
      ],

それぞれの操作を分けたコマンドとTeX からPNG, SVG を生成するコマンドを与えている.適宜調整してほしい.

コマンドパレットからLaTeX Workshop: Built with recipe とするか,keybindings.json で"latex-workshop.recipes" にショートカットキーを与えておけば,複数のレシピから自由に選択することが出来るようになる.


上のsettings.json を踏まえて以下の2つの方法がある.

standalone やpreview を使用する

  1. TeX を作成しPDF を生成(LuaLaTeX がオススメ)
  2. Convert PDF to PNG でPNG を生成

余白をトリミングする

  1. TeX を作成しA4 サイズ等のPDF を生成(ページ番号は非表示にしておく)
  2. Trimming PDF でPDF をトリミング
  3. Convert PDF to PNG でPNG を生成

注意 : これらのrecipe は開いているTeX ファイルのディレクトリ名からPDF をトリミング/ PNG に変換するものなので,TeX ファイルを開いていない場合にはもちろん実行できない.

まとめ

ネット上のConverter を利用しなくても自炊できる!! これでPowerPoint などのプレゼンに数式や表をPNG やSVG で挿入できるぞ!!!

と言いつつ,実はTeX2img を導入したら直で画像に出来るってマ???

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment