Graphics, Figures & TablesPNG and EPS images in PDF vs. DVI - Unified access

Information and discussion about graphics, figures & tables in LaTeX documents.
Post Reply
sdaau
Posts: 26
Joined: Fri Feb 19, 2010 2:08 pm

PNG and EPS images in PDF vs. DVI - Unified access

Post by sdaau »

Hi all,

Ok, well, this is the thing - I have to write a paper for a conference, where the style file is supplied; I build my .tex file with pdflatex, I obtain a .pdf file, and all is fine.

But then, maybe I want to convert the very same file to ODT (I am using texlive on Ubuntu):

Code: Select all

mk4ht oolatex mypaper.tex
or to HTML

Code: Select all

htlatex mypaper.tex
and the primary problem I bump into here, is that both mk4ht and htlatex seem to need a DVI file - the product of latex (instead of pdflatex) - in order to properly "understand" images in the file.

And of course:
  • pdflatex understands .pdf, .png, .jpg - but not .(e)ps
  • latex understands .(e)ps - but not .pdf, .png, .jpg
as content of the include graphics command.

Then, of course, I start wishing for some way that will automatically convert my images for the pdf oriented .tex file, whenever I am about to use latex. And although there are pointers that \DeclareGraphicsRule might help (for instance, in EPS Graphics - Kile Documentation), \DeclareGraphicsRule cannot in itself cause a conversion on the fly.

The closest I came to on-the-fly conversion is this "macro" (that "overloads"/renews \includegraphics):

Code: Select all

\let\oldIncludegraphics\includegraphics % save original snapshot
\renewcommand\includegraphics[2][]{% "overload" command
	%\message{FILENAME: #2}

	% create .bb file - not really needed
	\immediate\write18{ebb #2}

	% get eps filename based on png filename.
	% better to do it directly in Latex, than invoking system calls and reading files
	% get substring: "picture.png" -> "picture" as \plainfilename
	\def\temp ##1.png{%
		\def\plainfilename{##1}% "picture"
		\def\epsfilename{##1.eps}}% "picture.eps"
	\expandafter\temp#2 % this prepares both plainfilename and epsfilename

	% convert image to eps
	\immediate\write18{convert #2 \epsfilename}% create .eps file

	\message{EPSNAME: \epsfilename }
	\oldIncludegraphics[#1]{\plainfilename}% \plainfilename instead of #2
}
\fi
The idea is, that pdflatex would work without change, with images referenced by extension - and the first time latex needs to be run, it is run with --enable-write18 which causes automatic conversion to .eps.

Of course, the above would benefit best from being a style file (and being able to handle also other extensions than just .png, in a cross-platform manner...) So I was wandering - is there a better or more straightforward way of doing this?

In the next post, a bash transcript with minimal examples illustrating these problems is included.

Thanks for any comments,
Cheers!
Last edited by sdaau on Thu Apr 01, 2010 11:53 pm, edited 1 time in total.

Recommended reading 2024:

LaTeXguide.org • LaTeX-Cookbook.net • TikZ.org

NEW: TikZ book now 40% off at Amazon.com for a short time.

And: Currently, Packt sells ebooks for $4.99 each if you buy 5 of their over 1000 ebooks. If you choose only a single one, $9.99. How about combining 3 LaTeX books with Python, gnuplot, mathplotlib, Matlab, ChatGPT or other AI books? Epub and PDF. Bundle (3 books, add more for higher discount): https://packt.link/MDH5p

sdaau
Posts: 26
Joined: Fri Feb 19, 2010 2:08 pm

PNG and EPS images in PDF vs. DVI - Unified access

Post by sdaau »

Note that it should be possible to copy paste the below commands in a bash shell. In the following examples, I have used Exploring Perl Modules - Part 1: On-The-Fly Graphics with GD LG #81 to generate a png image on the fly; here are some other dependencies:

Code: Select all

# dependencies, if needed..
# in texlive, ebb is in dvipdfm package
tlmgr install dvipdfm

# use libgd-gd2-perl, so no need for perl -MCPAN -e shell, cpan[1]> install GD
sudo apt-get install libgd-gd2-perl

# for convert:
sudo apt-get install imagemagick

Here is a basic example (done in a new directory, test):

Code: Select all

mkdir test
cd test

# create red background image
perl -e "use GD; \$im = new GD::Image(100,100); \$red = \$im->colorAllocate(255,0,0); open(PICTURE, \">picture.png\") or die(\"Cannot open file for writing\"); binmode PICTURE; print PICTURE \$im->png; close PICTURE;"

cat > imgtest.tex <<EOF
\documentclass{article}
\usepackage{graphicx}
\begin{document}
This is a test document. \\
\begin{figure}[h]
\centering
\includegraphics{picture.png}
\caption{Some caption.}
\end{figure}
\end{document}
EOF

pdflatex imgtest.tex
# Output written on imgtest.pdf (1 page, 15115 bytes).

latex imgtest.tex
# ! LaTeX Error: Cannot determine size of graphic in picture.png (no BoundingBox)

# http://www.mps.mpg.de/homes/daly/latex/grf.htm#Q1-1-14
# The solution is to determine the bounding box coordinates somehow (see next point) and to include them, either in the \includegraphics command, or by editing the graphics file itself. However, if there really is no bounding box information in the file, it is unlikely to conform to the encapsulated standard and will cause other problems.

# OH NO, should we look for all bounding box data manually?
# maybe not: http://bmeps.sourceforge.net/examples.html#l12
# "The \DeclareGraphicsRule{.png}{eps}{.bb}{`bmeps #1} command tells LaTeX that PNG (*.png) files can be converted to EPS. The bounding box information for such files can be found in a file with the same name but the suffix ``.bb''. For the image fbt.png we have to create a file fbt.bb"
# also: http://kile.sourceforge.net/Documentation/html/build_epsgraphics.html
# so let's try with DeclareGraphicsRule:

cat > imgtest-decl.tex <<EOF
\documentclass{article}
\usepackage{graphicx}
\DeclareGraphicsRule{.png}{eps}{.bb}{\`convert #1 eps:-}%      PNG
\begin{document}
This is a test document. \\\\
\begin{figure}[h]
\centering
\includegraphics{picture.png}
\caption{Some caption.}
\end{figure}
\end{document}
EOF

pdflatex imgtest-decl.tex
# ! LaTeX Error: File `picture.bb' not found.

ebb picture.png
# produces picture.bb

pdflatex imgtest-decl.tex
# Output written on imgtest-decl.pdf (1 page, 26466 bytes).
# notice, previous pdf was 15115 bytes
# however, there is only a frame and the text "‘convert picture.png eps:-" written in it in the pdf

# test the command itself

convert picture.png eps:-
# %!PS-Adobe-3.0 EPSF-3.0
# %%Creator: (ImageMagick)
# ...
# %%PageBoundingBox: 0 0 100 100
# userdict begin
# DisplayImage
# ...
# 1
# FF0000
# 0000000000000000000000000000000000000000000000000000000000000000000000000000
# ...
# it seems to work...

# so we must use the DeclareGraphicsRule only in dvi mode!

cat > imgtest-decl.tex <<EOF
\documentclass{article}
\usepackage{graphicx}
\usepackage{ifpdf}
\ifpdf
% do nothing
\else
\DeclareGraphicsRule{.png}{eps}{.bb}{\`convert #1 eps:-}%      PNG
\fi
\begin{document}
This is a test document. \\\\
\begin{figure}[h]
\centering
\includegraphics{picture.png}
\caption{Some caption.}
\end{figure}
\end{document}
EOF

pdflatex imgtest-decl.tex
# Output written on imgtest-decl.pdf (1 page, 15361 bytes).
# looks OK now..

latex imgtest-decl.tex
# Output written on imgtest-decl.dvi (1 page, 384 bytes).

evince imgtest-decl.dvi
# you can see the bounding box, but not the image..

grep --text "convert" imgtest-decl.dvi
# cmr10?This?ETXUUis?a?test?do?G[GS]cumen???t.
#                                       ?l6?9????]q?FPSfile="`convert picture.png eps:-" #llx=0 lly=0 urx=72 ury=72 ....
This means that, contrary to my expectation, the 'convert' command is not ran during a latex run with \DeclareGraphicsRule, but is in fact verbatim included as a link to the final (converted) image. Which is probably why 'evince' will not render the image at all..

We can now try to simply remove the extension from the includegraphics command, and thereby force pdflatex and latex to choose their own extension...

Code: Select all

cat > imgtest-noext.tex <<EOF
\documentclass{article}
\usepackage{graphicx}
\begin{document}
This is a test document. \\
\begin{figure}[h]
\centering
\includegraphics{picture}
\caption{Some caption.}
\end{figure}
\end{document}
EOF

pdflatex imgtest-noext.tex
# Output written on imgtest-noext.pdf (1 page, 15360 bytes).
# looks OK..

latex imgtest-noext.tex
# ! LaTeX Error: File `picture' not found.

# lets try generate an eps file then..
convert -compress zip picture.png eps2:picture.eps

latex imgtest-noext.tex
# Output written on imgtest-noext.dvi (1 page, 368 bytes).

evince imgtest-noext.dvi
# now the image shows!

grep --text "picture" imgtest-noext.dvi
# cmr10?This?[ETX]UUis?a?test?do?G[GS]cumen???t.?QǍ?9????P?:PSfile="picture.eps" llx=0 lly=0 urx=100 ury=100 rwi=1000 ?[SYN]?????[NAK]Figure?[ETX]UU1:?[EOT]q?Some?caption.?[RS]???1??*[SOH]???[FS];[ETX]?[STX]y[SOH]?[SOH]?K?`y
So just like previously, simply a link to "picture.eps" is stored in the .dvi file - however, this one can be now easily interpreted by evince. (In fact, you could also open the imgtest-noext.dvi file in scite, and manually change "picture.eps" to "picture.png" - evince will still show the .dvi, but no image will be shown; although evince by itself can display png images)


Conclusion - DeclareGraphicsRule can be useful if you want to use full filenames, so it redirects requests for .png to say .eps - but it still will not take care of image conversion on the fly. So, seems that safest way to have the images correct in .dvi is to have eps versions of each requested image.


But is there a way to take care of this conversion on the fly, so we don't have to do all these conversion steps manually, if we want to switch from pdflatex to latex?

The only thing I can think of, is to interrupt the process whenever latex requests an image, do a system call that does an image conversion, and only then allow \includegraphics to execute. And that means that latex would have to be called with -shell-enable so it can run system commands - but it would have to be called like that only once; and that \includegraphics would have to be "overloaded". So let's try that (note that the code includes also a commented example, which uses bash to get the new eps filename in a file):

Code: Select all

rm * # delete everything in test dir

# create red background image
perl -e "use GD; \$im = new GD::Image(100,100); \$red = \$im->colorAllocate(255,0,0); open(PICTURE, \">picture.png\") or die(\"Cannot open file for writing\"); binmode PICTURE; print PICTURE \$im->png; close PICTURE;"

cat > imgtest-shl.tex <<EOF
\documentclass{article}
\usepackage{graphicx}
\usepackage{ifpdf}
\ifpdf
% do nothing
\else
% we will need explicit filenames here...
\let\oldIncludegraphics\includegraphics % save original snapshot
\renewcommand\includegraphics[2][]{% "overload" command
	%\message{FILENAME: #2}

	% create .bb file - not really needed
	\immediate\write18{ebb #2}

	% get eps filename based on png filename.
	% better to do it directly in Latex, than invoking system calls and reading files, as below
	% get substring: "picture.png" -> "picture" as \plainfilename
	\def\temp ##1.png{%
		\def\plainfilename{##1}% "picture"
		\def\epsfilename{##1.eps}}% "picture.eps"
	\expandafter\temp#2 % this prepares both plainfilename and epsfilename

	%% generate eps filename, store it in fname.txt
	%\immediate\write18{echo #2 | sed "s/png/eps/" > fname.txt}
	%
	%% read file contents into 'variable' / command: file fname.txt as \epsfilename
	%\def\tfn{fname.txt}
	%\newread\traux
	%\openin\traux=\tfn\relax
	%\read\traux to \InLine
	%\closein\traux
	%
	%% however, must get rid of the final space " " which is added..
	%\def\temp ##1 {%
	%	\def\epsfilename{##1}}% was \def\InLineNoSpace
	%\expandafter\temp\InLine % this should prepare epsfilename, by calling def

	% convert image to eps
	\immediate\write18{convert #2 \epsfilename}% create .eps file

	\message{EPSNAME: \epsfilename }
	\oldIncludegraphics[#1]{\plainfilename}% \plainfilename instead of #2
}
\fi
\begin{document}
This is a test document. \\
\begin{figure}[h]
\centering
\includegraphics{picture.png}
\caption{Some caption.}
\end{figure}
\end{document}
EOF

pdflatex imgtest-shl.tex
# Output written on imgtest-shl.pdf (1 page, 15360 bytes).

latex imgtest-shl.tex
# ! LaTeX Error: File `picture' not found.

latex --enable-write18 imgtest-shl.tex
# Output written on imgtest-shl.dvi (1 page, 368 bytes).
# generates also picture.eps

latex imgtest-shl.tex
# Output written on imgtest-shl.dvi (1 page, 368 bytes). - now it works fine

evince imgtest-shl.dvi
# picture can be seen fine

grep --text picture imgtest-shl.dvi
# cmr10?This?[ETX]UUis?a?test?do?G[GS]cumen???t.?QǍ?9????P?:PSfile="picture.eps" llx=0 lly=0 urx=100 ury=100 rwi=1000 ???????[NAK]Figure?[ETX]UU1:??q?Some?caption.?????1??*[SOH]????;[ETX]??y[SOH]?[SOH]?K?`y
Seems to work... And since we started with html and odt:

Code: Select all

mk4ht oolatex imgtest-shl.tex
# System call: cd sxw-imgtest-shl.dir; zip -r imgtest-shl.odt * ; cd ..
# generates imgtest-shl.odt

oowriter imgtest-shl.odt
# picture seen fine - though captions seem not supported..

htlatex imgtest-shl.tex
# [1 file imgtest-shl.html
# System call: convert -trim +repage -density 110x110 -transparent '#FFFFFF' zzimgtest-shl.ps imgtest-shl0x.png
# generates imgtest-shl.html, imgtest-shl0x.png

firefox imgtest-shl.html
# picture seems ok, but it is imgtest-shl0x.png - unfortunately, we needlessly go png-eps-png this way..
Just as a note, some nice resources that were helpful (especially with reading file contents into a command in latex): TeX: Reference and Examples by David Bausum: read, Macros: A Tutorial on \exapndafter, TEX beauties and oddities, LaTeX Community • View topic - Input text?

Cheers!
User avatar
T3.
Posts: 208
Joined: Fri Mar 14, 2008 12:58 pm

PNG and EPS images in PDF vs. DVI - Unified access

Post by T3. »

sdaau wrote:But is there a way to take care of this conversion on the fly, so we don't have to do all these conversion steps manually, if we want to switch from pdflatex to latex?

Code: Select all

\usepackage{epstopdf}
Cheers,

Tomek
sdaau
Posts: 26
Joined: Fri Feb 19, 2010 2:08 pm

PNG and EPS images in PDF vs. DVI - Unified access

Post by sdaau »

Hi Tomek,

Thanks for responding !
T3. wrote:

Code: Select all

\usepackage{epstopdf}
Just tried it - but it seems it is intended if you start writing for latex (with eps images) and then want to move to pdflatex (and so epstopdf will convert eps to pdf).

Unfortunately, the workflow I have is: a start in pdflatex (with png, jpg, pdf images) and I want to move to latex (.dvi output, which implies all of the above should be converted to .eps) - and epstopdf does not seem to work in this case; please look at the session below:

Code: Select all

mkdir test
cd test

# create red background image
perl -e "use GD; \$im = new GD::Image(100,100); \$red = \$im->colorAllocate(255,0,0); open(PICTURE, \">picture.png\") or die(\"Cannot open file for writing\"); binmode PICTURE; print PICTURE \$im->png; close PICTURE;"

cat > imgtest.tex <<EOF
\documentclass{article}
\usepackage{graphicx}
\usepackage{epstopdf}
\begin{document}
This is a test document. \\
\begin{figure}[h]
\centering
\includegraphics{picture.png}
\caption{Some caption.}
\end{figure}
\end{document}
EOF

pdflatex imgtest.tex
# ok

latex imgtest.tex
# ! LaTeX Error: Cannot determine size of graphic in picture.png (no BoundingBox)

latex --enable-write18 imgtest.tex
# Package epstopdf Warning: Drivers other than `pdftex.def' are not supported.
# ! LaTeX Error: Cannot determine size of graphic in picture.png (no BoundingBox)

cat > imgtest-rule.tex <<EOF
\documentclass{article}
\usepackage{graphicx}
\usepackage{epstopdf}
\epstopdfDeclareGraphicsRule{.png}{eps}{.eps}{%
  convert #1 #1.eps
}
\begin{document}
This is a test document. \\
\begin{figure}[h]
\centering
\includegraphics{picture.png}
\caption{Some caption.}
\end{figure}
\end{document}
EOF

pdflatex imgtest-rule.tex
# ! LaTeX Error: File `picture-png-converted-to.eps' not found.

pdflatex --enable-write18 imgtest-rule.tex
# ! LaTeX Error: File `picture-png-converted-to.eps' not found

latex --enable-write18 imgtest-rule.tex
# Package epstopdf Warning: Drivers other than `pdftex.def' are not supported
# Undefined control sequence.
# <recently read> \epstopdfDeclareGraphicsRule
I guess "Package epstopdf Warning: Drivers other than `pdftex.def' are not supported" is the key message here... (although picture.png.eps does get correctly generated somewhere in the above commands)

My last dash of hope is that maybe I misread The epstopdf package, and there is a proper setup of ***DeclareGraphicsRule that would work.. However:
»epstopdf« Manual wrote: Usually the drivers do not support all kind of graphics files. Other image
types must be converted, before they become usuable. In case of driver dvips,
the graphics rule may contain a conversion rule. Then all that package graphics
must know is the bounding box, the command is passed to dvips that calls it and
embeds the converted image.
However, pdfTEX has its driver for PDF output already build in. It’s graph-
ics inclusion commands (\pdfximage) does not allow the execution of external
commands. Therefore commands in the last argument of \DeclareGraphicsRule
were of no use. But external programs can be called within pdfTEX. This feature
is called “shell escape” or “write 18” and must usually enabled explicitely because
of security reasons. Now, this package epstopdf hooks into package graphics’ code
to catch that argument with the external command and executes it to convert the
graphics file to a supported format and passes the control of graphics inclusion
back to package graphics.
So, the starting point is that "dvips ... embeds the converted image" - which is why I guess this package would not intervene in latex generation of .dvi.

Cheers!
User avatar
localghost
Site Moderator
Posts: 9202
Joined: Fri Feb 02, 2007 12:06 pm

PNG and EPS images in PDF vs. DVI - Unified access

Post by localghost »

On a Linux machine I would recommend pfdtops for the PDF files. But you can always try ImageMagick. The forum search has some useful stuff about the latter one [1]. Pay special attention to the post of Tomek in that thread.

[1] View topic: Efficient JPG/PNG to EPS conversion?


Best regards
Thorsten
Adrien
Posts: 5
Joined: Wed Jun 23, 2010 8:59 pm

Re: PNG and EPS images in PDF vs. DVI - Unified access

Post by Adrien »

Hi sdaau,

I have exactly the same pb as what you explain, i.e. i use pdflatex and would like use mk4ht and have the same errors.
I quicly test the overload of includegraphics, but it seems that I have other packages not compatible with latex.

I test your bash script, but:
> latex --enable-write18 imgtest-shl.tex
latex: unrecognized option '--enable-write18'

Perhaps, you found an other solution to use mk4ht with pdflatex like file from the time of your first post.
Thanks for your very detailed post and hope to get a simple solution,
cheers,
Adrien
Post Reply