# Check for a valid file before using \includegraphics

I know how to check if a given argument represents an existing file (see this question).

But is there also a possibility to check if this file can be included by \includegraphics?

What I want to achieve is a command that

• includes an image (and does some more things) if it can, but
• includes some kind of info box and adds an entry to a 'list of missing images' if the argument doesn't point to a (existing and valid) image file.
-
Partial answer: you can always use the draft option for your documentclass to have empty boxes instead of the picture itself. –  Count Zero Feb 20 '13 at 11:48
Thanks, but that doesn't help. What I want is a system to highlight missing files and let them behave differently than normal ones. As a different (but improbable) approach: Is there something similar to 'raising exceptions' in programming languages, i.e. a construct like 'do something, but do something else if the original command doesn't work'? –  uli_1973 Feb 20 '13 at 11:56

# Second attempt

This here should do the same tests than \includegraphics. That means if will give yes if the graphics/file exists and if the extension can be handled be the engine (so tiger.eps will give different results with pdflatex and latex: (The code is from the definition of \Ginclude@graphics in graphics.sty).

\documentclass[]{article}
\usepackage{graphicx}

\makeatletter
\newif\ifgraphicexist

\catcode\*=11
\newcommand\imagetest[1]{%
\begingroup
\global\graphicexisttrue
\let\input@path\Ginput@path
\filename@parse{#1}%
\ifx\filename@ext\relax
\@for\Gin@temp:=\Gin@extensions\do{%
\ifx\Gin@ext\relax
\Gin@getbase\Gin@temp
\fi}%
\else
\Gin@getbase{\Gin@sepdefault\filename@ext}%
\ifx\Gin@ext\relax
\global\graphicexistfalse
\def\Gin@base{\filename@area\filename@base}%
\edef\Gin@ext{\Gin@sepdefault\filename@ext}%
\fi
\fi
\ifx\Gin@ext\relax
\global\graphicexistfalse
\else
\@ifundefined{Gin@rule@\Gin@ext}%
{\global\graphicexistfalse}%
{}%
\fi
\ifx\Gin@ext\relax
\gdef\imageextension{unknown}%
\else
\xdef\imageextension{\Gin@ext}%
\fi
\endgroup
\ifgraphicexist
\expandafter \@firstoftwo
\else
\expandafter \@secondoftwo
\fi
}
\catcode\*=12
\makeatother

\begin{document}

\imagetest{tiger}{Yes, \imageextension}{No, \imageextension}

\imagetest{tiger.eps}{Yes, \imageextension}{No, \imageextension}

\imagetest{fail}{Yes, \imageextension}{No, \imageextension}

\imagetest{failxxx.eps}{Yes, \imageextension}{No, \imageextension}

\imagetest{bib.bib}{Yes, \imageextension}{No, \imageextension}
\end{document}

-
Thank you for this solution. Probably I can use it as it is - although it will take some time until I understand what it actually does. There is one issue with it, though, and I'm not sure if it is implemented explicitely or by chance: If I pass the name of an existing but invalid file with its extension (e.g. melody.midi) to \imagetest it will report true (while if I only pass 'melody' it will correctly report false. If I can't solve this I can still document this, as one usually doesn't supply the extension to \includegraphics anyway. –  uli_1973 Feb 20 '13 at 15:21
@uli_1973: I have changed the code and now use all tests of \Ginclude@graphics. Hope this helps. –  Ulrike Fischer Feb 20 '13 at 16:04
Thank you very much, this seems to do it :-) Now I only have to understand why and how ... –  uli_1973 Feb 20 '13 at 16:31
@uli_1973: The core command is \Gin@getbase. It does the file checking. The rest are loops through the extension list and check of the results. –  Ulrike Fischer Feb 20 '13 at 16:40

it needs the full name of the file. You can scan the logfile for Imagefile to get all missing images files.

\documentclass{book}
\usepackage{graphicx}
\newcommand\IG[2][]{\IfFileExists{#2}
{\includegraphics[#1]{#2}}
{\fbox{File #2 doesn't exist}%
\message{Imagefile #2 doesn't exist^^J}}}% write a message into the log file

\begin{document}
\IG{foo}

\IG[width=3cm]{tiger.pdf}

\end{document}


-
As I understand it, while helpful for future readers, it is something the OP already knows. –  T. Verron Feb 20 '13 at 12:19
Yes, that's the way I would have gone without the option of asking here ;-) What I actually need is not to check if the file exists (although that already helps very much), but to check whether it exists and can be included - so I can do my error handling in both cases (missing/invalid file). –  uli_1973 Feb 20 '13 at 13:20
Also, I don't want to force the user to supply the full name. He should only have to supply the base name, as is usual with \includegraphics. So what I'd need is either a possibility to check if a file can be included by \includegraphics (preferrable this should be generic, so the result of the test is correct on the actual platform it is run) or to 'redirect' an error raised by \includegraphics so I can execute an alternative code block –  uli_1973 Feb 20 '13 at 13:24

\documentclass[preview,border=12pt,varwidth]{standalone}
\usepackage{graphicx}

\newwrite\writer
\immediate\openout\writer=missing.txt\relax

\newcommand\IG[2][]{\IfFileExists{#2}
{\includegraphics[#1]{#2}}
{\immediate\write\writer{\unexpanded{#2\newline}}}}

\begin{document}
\IG{foo.ext}

\IG[width=3cm]{example-image-a.pdf}

\IG{goo.eps}

\IG{hoo.png}

\section*{Missing Graphics}
\immediate\closeout\writer
\input{missing.txt}

\end{document}

-
You can also use \errmessage to notify or \typeout to log the missing files. –  Please don't touch Feb 20 '13 at 12:48
Thanks for these alternatives for the error handling, but unfortunately the solution does (as Answer #1) only check for the existence of the file. –  uli_1973 Feb 20 '13 at 13:21

I would like to share the final result from what I got on stackexchange. Maybe it is of use for someone ...

The following document implements a 'public' command printFigure that is to be placed within a floating environment (like figure in this example). It takes the same two arguments as \includegraphics.

If the given filename points to a valid image file the command behaves normally, but if it can't print the image it prints a colored box instead and colors the lof entry.

The point of this isn't mainly to notice missing image files (which is already quite handy because I manage everything with remote Git repositories and have to generate image file on each computer separately. More important is the option to enter images that aren't created yet, just to get the structure clearer while writing the document.

I will soon rerelease this as part of a package that manages music examples.

\documentclass[]{article}
\usepackage{caption}
\usepackage{xcolor}

\makeatletter
\newif\ifgraphicexist

\catcode\*=11

\newcommand\ifvalidimage[1]{%
\begingroup
\global\graphicexisttrue
\let\input@path\Ginput@path
\filename@parse{#1}%
\ifx\filename@ext\relax
\@for\Gin@temp:=\Gin@extensions\do{%
\ifx\Gin@ext\relax
\Gin@getbase\Gin@temp
\fi}%
\else
\Gin@getbase{\Gin@sepdefault\filename@ext}%
\ifx\Gin@ext\relax
\global\graphicexistfalse
\def\Gin@base{\filename@area\filename@base}%
\edef\Gin@ext{\Gin@sepdefault\filename@ext}%
\fi
\fi
\ifx\Gin@ext\relax
\global\graphicexistfalse
\else
\@ifundefined{Gin@rule@\Gin@ext}%
{\global\graphicexistfalse}%
{}%
\fi
\ifx\Gin@ext\relax
\gdef\imageextension{unknown}%
\else
\xdef\imageextension{\Gin@ext}%
\fi
\endgroup
\ifgraphicexist
\expandafter \@firstoftwo
\else
\expandafter \@secondoftwo
\fi
}
\catcode\*=12
\makeatother

% Now define a command that colors a lof entry red.
% This is necessary because the parts in \DeclareCaptionListFormat
% are put in separate groups by LaTeX.
\DeclareRobustCommand{\colortwogroups}{\makeredaux\aftergroup\makeredaux}
\newcommand\makeredaux{\color{red}}

% Declare a caption list format for use with missing images
\DeclareCaptionListFormat{missingfig}{\colortwogroups#1 #2}

\newcommand{\printFigure}[2][]{%
\ifvalidimage{#2}
{% If we have a correct image file:

\noindent
% 'max width' courtesy of adjustbox
\includegraphics[max width=\textwidth,#1]{#2}

}%
{% if we don't find an appropriate image:

\bigskip
% make the caption red (in the \listoffigures)
\captionsetup{listformat=missingfig}%
% print a box instead of the image
\fcolorbox{red}{yellow}{%
\parbox[c]{.7\textwidth}{~\\
\textbf{\textsf{Missing image:}}\\
#2\\
}
}

\bigskip
}
}

\begin{document}

\begin{figure}
\printFigure{bsp1}
\caption{A quite fancy music example}
\end{figure}

\begin{figure}
\printFigure{bsp2}
\caption{Another quite fancy music example}
\end{figure}

\listoffigures

\end{document}


-
Be careful with white spaces in your code above and you can use \fcolorbox{<rule color>}{<background color>}{<object>} instead of \framebox{\colorbox{...}}. –  Please don't touch Feb 21 '13 at 1:23
Thanks for the hints. I updated the \fboxcolor thing (now the image doesn't correspond to the output anymore). Concerning whitespace: I'm not sure if I understand you or if I really have issues in my code. I didn't use percents everywhere because I created new items, paragraphs etc. anyway. Would you consider it good practice to use percents everywhere? And the empty lines are there to create new paragraphs. But I admit I know that I tend to try to format my code with generous whitespace, due to my background from programming languages. –  uli_1973 Feb 21 '13 at 9:03
Please carefully see the padding on the right of your \framebox, is it equal to the one on the left? I don't think so. The white spaces right after } are also "dangerous". –  Please don't touch Feb 21 '13 at 9:18
Thankyou for the clarification. The image actually wasn't balanced, but that has probably vanished by itself through the change to \fcolorbox. The spaces preceding the %` at line endings result from my new editor that adds them automatically (and me not yet being used to that). However I left the percent signs out at the endings of the last lines closing the command (because they are creating a new paragraph after the box anyway). –  uli_1973 Feb 21 '13 at 10:07