2

For a quite large document I'm using the external library from tikz. However, to annotate an image I tried to include it in a tikzpicture node and then draw on it.

My problem is, that I have defined a new command \includegraphicscoloured, which replaces the default \includegraphics, such that it supports an additional file suffix (for me "-monochrome" or "-rgb", defined before in the preamble). Now, when I compile the document, my image does not get included, but I only get the text

[includegraphics optimized away because it does not contribute to exported PDF]

When I use the default \includegraphics everything is fine. I can also get it to work, when I globally use tikzset{external/optimize=false}, but that is not really an option, since then every single externalisation takes ages.

I tried putting the external/optimize key directly at the tikzpicture environment or simply inside my newly defined macro, but none of this worked out.

Is there a way that I can switch optimisation off for only that single picture? Or are there things I can modify in the tikzexternalize settings that help? I read the docs, but could not find any details on the process.

MWE:

\documentclass{article}

\usepackage{mwe}
\usepackage{tikz}
\usetikzlibrary{external}
\tikzexternalize[optimize=true]

\def\imageSuffix{-monochrome}

% This line is only here to stop TeXnicCenter from complaining
%   that the image #2\tikzExternalSuffix does not exist
\let\latexincludegraphics\includegraphics   
\newcommand{\includegraphicscoloured}[2][]{%
    % we have to define the filename to test for in a macro,
    %   otherwise it just fails
    \def\testfile{./#2\imageSuffix}%
    %
    % now test if the picture exists as
    %   pdf, png, or jpg
    \IfFileExists{\testfile.pdf}{%
        % pdf version of file exists
        \latexincludegraphics[#1]{#2\imageSuffix}%
    }{%
        \IfFileExists{\testfile.jpg}{%
            % jpg version of file exists
            \latexincludegraphics[#1]{#2\imageSuffix}%
        }{%
            \IfFileExists{\testfile.png}{%
                % png version of file exists
                \latexincludegraphics[#1]{#2\imageSuffix}%
            }{%
                % no known version of the suffixed image exists
                %   thus fallback to normal include, which will
                %   print it's own error when it fails
                \latexincludegraphics[#1]{#2}%
            }
        }
    }
}

\begin{document}
    \begin{figure}
        \begin{tikzpicture}
            \node at (0, 0) {\includegraphics[width=0.5\columnwidth]{example-image-a}};
        \end{tikzpicture}
        \caption{This works as expected.}
    \end{figure}
    \begin{figure}
        \begin{tikzpicture}
            \node at (0, 0) {\includegraphicscoloured[width=0.5\columnwidth]{example-image-b}};
        \end{tikzpicture}
        \caption{This doesn't: ``includegraphics optimized away because it does not contribute to exported PDF''.}
    \end{figure}
\end{document}
  • Welcome to TeX.SX! – ebosi Dec 5 '16 at 15:36
  • Changing the \let line to \def\latexincludegraphics{\includegraphics} will work. – Symbol 1 Dec 6 '16 at 20:00
  • @Symbol1: That indeed solved the problem. For anyone else, [this] (tex.stackexchange.com/a/318/100384) Stack Exchange question answers the difference between \let and \def, which probably helps here, too. Short beginner question, should there be an answer made for this, or would I leave the question open? – Timm Dec 8 '16 at 9:52
1

The motivation of external/optimize is that when you turn on the externalization, TikZ will reread the whole document for every single picture. An evidence of this is that if you defined, say, \def\n{100}, outside tikzpicture, TikZ seems to remember the definition so that you can use \n inside the tikzpicture. In other words, TikZ spends a lot of time rereading a bunch of unrelated stuff just to make sure you did not hide the definition of \n somewhere deep.

When you turn on external/optimize, TikZ will try to save some time by ignoring expensive macros such as \includegraphics. Nonetheless, it will turn on \includegraphics while it thinks it need it.

Back to your code: when you say \let\latexincludegraphics\includegraphics, you actually finalize the definition of \latexincludegraphics; your macro will not be changed even though TiKZ changes the definition of \includegraphics. And since by the time you finalize the definition of your macro the \includegraphics is turned off, your macro is not going to work properly.

There are two ways to fix this. One is, like I commented, to use \def instead of \let. By doing so the function of your macro will change whenever TikZ makes any change. And the other one is to finalized the definition of \latexincludegraphics before TikZ can turn it off.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.