# Selectively use PNG or PDF for externalized TikZ pictures

It is possible to ask the code for externalizing TikZ pictures to convert the generated PDF to PNG figures thanks to ImageMagics.

This however gives higher figure weight for some light figures.

What I would like is to have a weight checking code to pick the lightest figure of the two. This way, light figures would remain vectorial (which is ideal), and heavier ones would become PNG (which allows for more reasonable weight, which saves space and display time).

I work with quite a lot of figures ranging from 20ko to 9MO in their PDF externalized function. they are generated automatically from loops, which makes the manual selection a problem.

Here is a MWE, where Ideally the first figure would be vectorial, and the second PNG in an automatic way (here I manually forced it).

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{external}
\tikzexternalize[mode=list and make]

\tikzset{
png export/.style={
% First we call ImageMagick; change settings to requirements
external/system call/.add={}{; convert -density 100 -transparent white "\image.pdf" "\image.png"},
% Now we force the PNG figure to be used instead of the PDF
/pgf/images/external info,
/pgf/images/include external/.code={
\includegraphics[width=\pgfexternalwidth,height=\pgfexternalheight]{##1.png}
},
}
}

\begin{document}

\begin{tikzpicture}
\draw (0,0) circle (1) ;
\end{tikzpicture}

% Activate the plot as png
\tikzset{png export}

\begin{tikzpicture}
\foreach \xnum in {1,2,3,...,99,100}
{
\draw (0,0) circle (1) ;
}
\end{tikzpicture}

\end{document}


Basically, I think this may be possible to add some code in the /pgf/images/include external/.code, to look at the size, and with some logic, decide to use the PNG or the PDF.

• Wouldn't it be easier to post-process the externalised images? If all the externalised images are in a sub-directory, then you could just run a script to convert those you want converted. Then you change the .tex file to just include the externalised images without checking if they need updating. (I'm assuming this is something you'll only want to do when the document is finalised anyhow.) – cfr Jan 24 '17 at 1:38
• @cfr this is actually a way I'm thinking of. I may have a special file to only generate the figures, then run some commands in order to convert the too heavy ones and copy only the lighters to a folder. Then \includegraphics without extensions in the main file. – Togh Jan 24 '17 at 22:18

Apparently you can expand the system call as follows:

    external/system call/.add={}{;
convert -density 100 -transparent white "\image.pdf" "\image.png";
wc -c "\image.pdf" | awk '{print "PDF is " $1}'; wc -c "\image.png" | awk '{print "PNG is "$1}';
echo "what is next? sir?"
}


This will give you

Now you can program your logic by shell.

• This approach could work if I could delete the pdf. I could just delete the unwanted picture so there would remain only one. However, this mean the PDF would be rebuilt on each run in the case when the PNG is kept, which is a problem as heavy to generate. An alternative would be to have a separate folder where the picture to plot is sent. I'm trying this right now. – Togh Jan 26 '17 at 19:13
• Mh, I don't know how to modify the path to ##1, and if I know how to modify it, I do not need to make the separate folder. – Togh Jan 26 '17 at 19:16
• @Togh A must-work way is to create a file \image.choice.tex that contains either \includegraphics{\image.pdf} or \includegraphics{\image.png}. And then change /pgf/images/include external/.code=\input{\image.choice.tex} – Symbol 1 Jan 26 '17 at 19:21
• I've made a try with something similar in the logic, but seems part of the commands do not execute correctly. – Togh Jan 26 '17 at 19:35

Based on the discussion with @Symbol 1 , I have come to this:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{external}
\tikzexternalize[mode=list and make]

\tikzset{
png export/.style={
% First we call ImageMagick; change settings to requirements
external/system call/.add={}{; convert -density 100 -transparent white "\image.pdf" "\image.png";
mkdir -p fig2plot;
if [[ wc -c "\image.pdf" | cut -d' ' -f1; -lt wc -c "\image.png" | cut -d' ' -f1; ]];
then cp "\image.png" fig2plot;
else cp "\image.pdf" fig2plot;
fi},
% Now we force the PNG figure to be used instead of the PDF
/pgf/images/external info,
/pgf/images/include external/.code={
\includegraphics[width=\pgfexternalwidth,height=\pgfexternalheight]{fig2plot/##1}
},
}
}

\begin{document}

% Activate the plot as png
\tikzset{png export}

\begin{tikzpicture}
\draw (0,0) circle (1);
\end{tikzpicture}

\begin{tikzpicture}
\foreach \xnum in {1,2,3,...,99,100}
{
\draw (0,0) circle (1) ;
}
\end{tikzpicture}

\end{document}


It creates a subfolder where it copies the smallest image, than plot from that subfolder whatever the extension.

However, while the commands in the makefile works in the shell, the if seems to have a flaw:

/bin/sh: 1: [[: not found


And both figures in the folder are pdf (so the if is always false, whereas when I try the command in bash it gives the right answer).