Export to image (TeX2img/dvisvgm/ImageMagick)

A figure drawn in LaTeX is already vector art before you export anything — the axes exist as curves, the labels as glyphs from a font. And yet, the moment you export it as an image, that information is thrown away with startling ease. What decides whether it is thrown away happens much earlier than most people assume: it is the single choice of going through DVI or going through PDF. The dvisvgm manual states it flatly — text present in PDF and PostScript files is always converted to path elements. Pass through a PDF and the letters in your figure stop being letters. This page lays out standalone, pdfcrop, dvisvgm and rasterising around exactly that pivot.

Putting just the figure on one page: the standalone class

The first step in exporting is to make the paper the size of the figure. Martin Scharrer's standalone class (v1.3b in TeX Live 2024) sets the page dimensions to the dimensions of the content. Putting nothing but $\displaystyle \int_{-\infty}^{\infty} e^{-x^2}\,dx = \sqrt{\pi}$ into \documentclass[border=2pt,preview]{standalone} and running pdflatex here produced a PDF whose page size was 85.779 × 27.993 pt — the outline of the formula itself. Leave border out and the default is 0pt. The class itself hardcodes an oddly precise 0.50001bp — there to stop rounding from shaving the edge off a glyph — but the shipped standalone.cfg overrides it with \standaloneconfig{border=0pt} just before options are processed. For a TikZ drawing, use \documentclass[tikz,border=2pt]{standalone} and put the tikzpicture directly after \begin{document}. To cut out a fragment of running text that should wrap, give it a width with something like varwidth=10cm. The preview package that standalone uses underneath was originally written for preview-latex in Emacs's AUCTeX — the idea of typesetting only a slice of a document comes from there.

latex
% fig.tex — a figure that is its own page
\documentclass[tikz,border=2pt]{standalone}
\begin{document}
\begin{tikzpicture}
  \draw[thick,->] (0,0) -- (3,0) node[right] {$x$};
  \draw[thick,->] (0,0) -- (0,2) node[above] {$y$};
  \draw[blue,thick] (0,0) .. controls (1,2) .. (3,1);
\end{tikzpicture}
\end{document}

Trimming the margins off a PDF you already have: pdfcrop

When the figure lives inside an ordinary document and cannot be rebuilt, pdfcrop will do. It is a Perl script by Heiko Oberdiek (v1.42 in TeX Live 2024) that computes the bounding box of the page content and shrinks the trim box to it. Measured here, a one-page letter-size document of 612 × 792 pt came out of pdfcrop doc.pdf doc-crop.pdf at 345 × 539 pt. If you do not want the margin to be zero, --margins 10 puts 10 pt back on each side, giving 365 × 559 pt. One caveat: pdfcrop calls Ghostscript — the top of the script says so outright, “Requirements: Perl5, Ghostscript”. Without gs installed it will not run. And note that if you can build the figure with standalone in the first place, you do not need pdfcrop at all: not making the margin is faster and more accurate than cutting it off.

terminal
pdfcrop doc.pdf doc-crop.pdf              # 612x792 pt becomes 345x539 pt
pdfcrop --margins 10 doc.pdf doc-crop.pdf # keep 10 pt on every side
pdfcrop --hires doc.pdf doc-crop.pdf      # use the high-resolution bounding box

Making an SVG: dvisvgm, and why the DVI route wins

For a figure headed to the web, SVG is the first candidate. Martin Gieseking's dvisvgm (3.2.2 in TeX Live 2024) converts DVI, EPS and PDF to SVG — but what comes out depends on which door you came in by. Putting \def\pgfsysdriver{pgfsys-dvisvgm.def} before \documentclass, producing a DVI with latex and running dvisvgm fig.dvi, the resulting SVG held the axes and the curve as <path> elements and the labels $x$, $y$ and $y=f(x)$ as <text> elements — letters still letters, referring to vector fonts embedded in <defs>. Enter through a PDF and that does not happen. The dvisvgm manual is explicit that text present in PDF and PostScript files is always converted to path elements. Sure enough, running poppler's pdftocairo -svg on the PDF of the same figure gave an SVG with zero <text> elements.

latex
% figdvi.tex — the DVI route, which keeps the labels as real text
\def\pgfsysdriver{pgfsys-dvisvgm.def}
\documentclass[tikz,border=2pt]{standalone}
\begin{document}
\begin{tikzpicture}
  \draw[thick,->] (0,0) -- (3,0) node[right] {$x$};
  \draw[blue,thick] (0,0) .. controls (1,2) .. (3,1);
\end{tikzpicture}
\end{document}
terminal
latex figdvi.tex        # produce a DVI, not a PDF
dvisvgm figdvi.dvi      # SVG with <text> elements and vector paths

# the PDF route needs a helper and outlines all text:
dvisvgm --pdf fig.pdf   # requires mutool with Ghostscript 10.01 or newer

There is a further, practical obstacle to going from PDF to SVG. dvisvgm --pdf used to hand the PDF to Ghostscript, but according to the manual the new PDF interpreter introduced in Ghostscript 10.01.0 broke that path, and dvisvgm now looks for MuPDF's mutool instead. On the machine used for this article (Ghostscript 10.03.0, no mutool), dvisvgm --pdf fig.pdf stops with ERROR: can't retrieve number of pages from file fig.pdf. So the PDF route demands an extra dependency, and whenever Ghostscript is the one handling the file the manual's rule applies and the text is outlined regardless — two reasons to prefer the DVI route. One more option worth remembering is -e (--exact-bbox): by default the bounding box is derived from TFM metrics, so a glyph that actually overhangs them can get clipped. If letters are shaved off at the edge of a figure, reach for this first.

What to do about fonts in the SVG: --font-format and --no-fonts

Keeping <text> is good, but it needs one more decision. The default in dvisvgm is SVG fonts<font> and <glyph> embedded in <defs> — which exist in the specification but are not supported nearly everywhere; dvisvgm's own manual says under --no-fonts that path output is “more compatible with most applications that don't support SVG fonts”. Comparing all three on the same TikZ figure: the default SVG fonts gave 5,790 bytes, --font-format=woff2 gave 4,815 bytes (a WOFF2 embedded as a data URI in the src of an @font-face rule), and --no-fonts gave 8,290 bytes with zero <text> elements and every glyph turned into a <path>. The practical rule is simple. Going on the web: --font-format=woff2 — the text stays selectable and every browser can draw it. Handing the file to Illustrator, Inkscape or PowerPoint: --no-fonts — bigger, but nothing is left that could render wrongly.

OptionText inside the SVGSize on the same figureWhat it suits
--font-format=svg<text> plus SVG fonts (the default)5,790 bytessupport is patchy; rarely the right choice
--font-format=woff2<text> plus a WOFF2 embedded in @font-face4,815 bytespublishing on the web; selectable text, smallest file
--no-fontsno <text> at all; every glyph is a <path>8,290 byteshanding the file to other drawing software; nothing can render wrongly

Rasterising to PNG, for slides and older tools

Plenty of destinations still refuse SVG, and then you fall back to PNG. Resolution is set with -r; treat 300 dpi as a floor and 600 dpi as the target for print or high-density displays. Rasterising the 85.779 × 27.993 pt formula PDF built above at 600 dpi produced a transparent PNG of about 715 × 233 pixels — both from Ghostscript (gs -sDEVICE=pngalpha -r600) and from poppler's pdftocairo -png -r 600 -transp. Since 72 pt is one inch, 85.779 ÷ 72 × 600 ≈ 715; checking that the arithmetic works out is how you confirm the resolution flag actually took effect. If you do not want transparency, -sDEVICE=png16m (or dropping -transp from pdftocairo) gives a white background. Many write-ups recommend ImageMagick's magick -density 300 in.pdf out.png, but ImageMagick delegates PDF rendering to Ghostscript. It is not part of TeX Live and was not installed on the machine used here, so its behaviour has not been checked. When Ghostscript is what actually draws the page, calling it directly is one dependency fewer.

terminal
# Ghostscript, transparent background, 600 dpi
gs -q -dNOPAUSE -dBATCH -sDEVICE=pngalpha -r600 \
   -dTextAlphaBits=4 -dGraphicsAlphaBits=4 \
   -sOutputFile=eq.png eq.pdf

# poppler, same result, shorter to type
pdftocairo -png -r 600 -transp -singlefile eq.pdf eq

From source to PNG in one command: standalone's convert= and --shell-escape

If typing three commands every time grates, hand the job to standalone's class option convert=. The class itself throws a conversion command at the shell the moment typesetting finishes. The backend can be imagemagick (the default), ghostscript or pdf2svg, and the default resolution is density=300. Even without ImageMagick, naming ghostscript works: with \documentclass[border=2pt,convert={ghostscript,density=600,outext=.png}]{standalone} and pdflatex --shell-escape eqc.tex, the log showed gs -dSAFER -dBATCH -dNOPAUSE -sDEVICE=png16m -r600 -sOutputFile=eqc.png eqc.pdf and a 715 × 233 PNG appeared from that single command. Because it launches an external program, restricted shell escape is not enough — you need --shell-escape. On a project with many figures it is safer to keep the conversion in a build script, so that --shell-escape does not become a habit.

latex
% eqc.tex — build the PNG in the same run
\documentclass[border=2pt,convert={ghostscript,density=600,outext=.png}]{standalone}
\usepackage{amsmath}
\begin{document}
$\displaystyle \int_{-\infty}^{\infty} e^{-x^2}\,dx = \sqrt{\pi}$
\end{document}

% then: pdflatex --shell-escape eqc.tex

Everything above — typeset only the fragment, crop it, then take it to vector or raster — is what TeX2img wraps in a graphical interface. You paste in a formula, choose a format and a resolution, and it handles transparency and anti-aliasing for you. For a one-off export it is unbeatably quick; for a document with dozens of figures that goes through many revisions, folding the commands from the sections above into your build is easier in the end. Note that TeX2img is a separate application, not part of TeX Live, and it was not installed on the machine used here, so its behaviour has not been checked.

Which format to export to

  • A figure going on the web → SVG. Produce a DVI with latex and run dvisvgm --font-format=woff2. The text stays inside <text> and nothing degrades when zoomed.
  • A figure to be pulled back into a LaTeX document → leave it as PDF. Built with standalone it has no margin and goes straight into \includegraphics.
  • Slides, Word, social media → PNG, via gs -sDEVICE=pngalpha -r600 or pdftocairo -png -r 600 -transp. Drop the transparency only when you want a white background.
  • A figure you will retouch in Illustrator or Inkscape → SVG with --no-fonts. The shapes hold even where the font is missing.
  • A figure containing a photograph → JPEG for the photograph only; line art and labels as SVG or PNG. Making the whole thing a JPEG dirties the edges of the letters.
  • When dvisvgm --pdf refuses to run → switch to the DVI route first. If it really must come from a PDF, install MuPDF's mutool.