1

I am trying to use beamer to generate multiple images with some animation effect. Posting my code here (the code content is not relevant, just for easy demo the problem I met).

\documentclass[border=5mm, convert, usenames, dvipsnames]{beamer}
\usepackage{tikz, pifont, xcolor}
\usepackage[export]{adjustbox}
\usetikzlibrary{shapes, positioning, calc, arrows.meta, fit, backgrounds}
\usetikzlibrary{overlay-beamer-styles}
\usetikzlibrary{scopes}
\usepackage{lmodern}
\usepackage{underscore}

\pgfkeys{/tikz/savenumber/.code 2 args={\global\edef#1{#2}}}
\newcommand*\mydots{{\fontsize{60}{80}\selectfont$\cdots$}}

\makeatletter
\geometry{papersize={64cm,64cm}}
\tikzset{use path/.code={\pgfsyssoftpath@setcurrentpath{#1}}}
\makeatother

\begin{document}
    \tikzset{myfunc/.style n args = {4}{font=\footnotesize \ttfamily, align=left, rounded corners, rectangle, minimum width=#1cm, minimum height=#2cm, fill=#3, draw=#4}}
    \tikzset{myfunc/.default={3}{4}{white}{black}}
    \tikzset{mytask/.style n args = {4}{font=\footnotesize \ttfamily, align=left, rounded corners, double, rectangle, minimum width=#1cm, minimum height=#2cm, fill=#3, draw=#4}}
    \tikzset{mytask/.default={3}{4}{white}{black}}
    \tikzset{desctext/.style = {font=\footnotesize \sffamily, align=left, color=Mahogany}}
    \tikzset{mycon/.style = {rounded corners}}
    \tikzset{demotext/.style = {font=\Huge \bfseries, fill opacity=1,text opacity=1}}
    \tikzset{horizenjoin/.style = {to path={(\tikztostart.east) -- ($(\tikztostart.east)!0.5!(\tikztostart.east-|\tikztotarget.west)$)|- (\tikztotarget.west)}, rounded corners}}

    \begin{frame}[c, fragile]
    \begin{tikzpicture}[auto, >={Latex[angle=45:5pt 2]}]
        \only<+-> {
            \node [myfunc, save path=\stagingpath] (staging) {}; 
            \node at (staging.north west) [anchor=north west, align=left] {};
            \node [myfunc, right = of staging, save path=\localbranchpath] (localbranch) {};
            \node at (localbranch.north west) [anchor=north west] {};
            \draw let \p1=($(staging.west)-(localbranch.east)$), \n2={veclen(\x1, \y1)} in node [myfunc, minimum width = \n2, below = 1cm of staging.south west, anchor = north west, save path=\workingpath] (worktree) {};
            \node at (worktree.north west) [anchor=north west] {};

            % big picture
            \draw let \p1=($(staging.west)-(localbranch.east)$), \n2={veclen(\x1, \y1)} in node [myfunc, minimum width = \n2, below = 1cm of worktree.south west, anchor = north west] (stash) {};
            \node at (stash.north west) [anchor=north west] {};

            \draw let \p1=($(staging.west)-(localbranch.east)$), \n2={veclen(\x1, \y1)}, \p3=($(staging.north)-(staging.north|-stash.south)$), \n4={veclen(\x3, \y3)} in node [myfunc, minimum width = \n2, minimum height = \n4, right = 1cm of localbranch.north east, anchor = north west, save path=\remotepath] (remote) {};
            \node at (remote.north west) [anchor=north west, align=left] {};

            \draw let \p1=($(staging.west)-(localbranch.east)$), \n2={veclen(\x1, \y1)}, \p3=($(staging.north)-(staging.north|-stash.south)$), \n4={veclen(\x3, \y3)} in node [myfunc, minimum width = \n2, minimum height = \n4, right = 4cm of remote.north east, anchor = north west, save path=\serverpath] (serverrepo) {};
            \node at (serverrepo.north west) [anchor=north west, align=left] {};

            \node [rectangle, fit=(staging)(remote), draw, line width = 0.5mm, inner sep=1cm, rounded corners, blue] (mypc) {};
            \node at (mypc.north west) [anchor=north west, blue, font=\huge] {};

            \node [rectangle, fit=(serverrepo), draw, line width = 0.5mm, inner sep=1cm, rounded corners, violet] (server) {};
            \node at (server.north west) [anchor=north west, violet, font=\huge] {};

            \draw let \p1=(server.north west),\p2=(server.south east),\n1={0.6*(\x2-\x1)},\n2={0.2*(\y1-\y2)} in node [rectangle, draw, right = 1.5cm of server.north east, anchor=north west, rounded corners, Bittersweet, minimum width=\n1, minimum height=\n2] (colleague1) {} [savenumber={\wid}{\n1}, savenumber={\hei}{\n2}];
            \node at (colleague1.north west) [anchor=north west, Bittersweet, font=\LARGE] {};
            \node [rectangle, draw, below = of colleague1, rounded corners, ForestGreen, minimum width=\wid, minimum height=\hei] (colleague2) {};
            \node at (colleague2.north west) [anchor=north west, ForestGreen, font=\LARGE] {};
            \node [rectangle, draw, right = 1.5cm of server.south east, anchor=south west, rounded corners, Magenta, minimum width=\wid, minimum height=\hei] (colleague3) {};
            \node at (colleague3.north west) [anchor=north west, Magenta, font=\LARGE] {};

            \path (colleague2.south) -- (colleague3.north) node [font=\Huge, pos=0.2, sloped, ForestGreen!50!Magenta] {\mydots};
        }

        \only<+> {
            \fill [even odd rule, fill=green, opacity=.5, rounded corners] ([xshift=-0.5cm, yshift=0.5cm]staging.north west) rectangle ([xshift=0.5cm, yshift=-0.5cm]remote.south east) ([xshift=-0.5cm, yshift=0.5cm]worktree.north west) rectangle ([xshift=0.5cm, yshift=-0.5cm]worktree.south east);
            \node [demotext, above = of mypc.north west, anchor=south west, fill=blue, white] {animation 1};
        }

        \only<+> {
            \fill [fill=green, opacity=.5, rounded corners] ([xshift=-0.5cm, yshift=0.5cm]worktree.north west) rectangle ([xshift=0.5cm, yshift=-0.5cm]worktree.south east);
            \node [demotext, above = of mypc.north west, anchor=south west, fill=blue, white] {animation 2};
        }
    \end{tikzpicture}
    \end{frame}
\end{document}

I can generate a 3 page pdf. For some reason I want to get 3 separate png as well. The problem is, when I use convert tool to convert it to png

convert target.pdf target-%02d.png

The generated png's image quality is very poor.

I am wondering if I can generate png directly from the source, just like when I am using the standalone class.

Another related problem is that, I am changing the page size using the geometry command, in order to hold a big enough image, I am setting it rather large in the first place. It turns out I need to crop the generated image to remove blank area.

I can do this manually with -crop. However, I do not want to adjust the crop parameters by hand and want to seek for a smarter crop, then I find -trim. However when I use this with convert, it only crops the north west corner of the page. How to let -trim work for all sides of the image?

===== Update per @samcarter suggestion =====

Simplify the example as the following

\documentclass[border=5mm, convert, usenames, dvipsnames]{beamer}
\usepackage{tikz, pifont, xcolor}
\usepackage[export]{adjustbox}
\usetikzlibrary{shapes, positioning, calc, arrows.meta, fit, backgrounds}
\usetikzlibrary{overlay-beamer-styles}
\usetikzlibrary{scopes}
\usepackage{lmodern}
\usepackage{underscore}

\makeatletter
\geometry{papersize={64cm,64cm}}
\makeatother

\begin{document}
    \begin{frame}[c, fragile]
        \begin{tikzpicture}
            \only<+-> {
                \node [draw, rectangle, minimum width=4cm, minimum height=3cm] {Sample};
            }

            \only<+> {
                \node [fill=green, rectangle, minimum width=4cm, minimum height=3cm, opacity=0.5] {};
            }

        \end{tikzpicture}
    \end{frame}
\end{document}

Then use the convert to make the png, for simplicity I just convert the first page

convert -density 3000 simple_question.pdf[0] simple_image.png

The following is the comparison of image in pdf and in png with similar scaling.

PNG in left, PDF in right

As can be seen, in PNG the line and text is a bit distorted, while in PDF there is no such problem.

I have followed @KJO's advice to use larger density, but seems no effect.

When I use the standalone class, I have also make very big pictures, but there the png is always with good quality, not sure what is the command line used for that class.


Eric Sun
  • 401
  • Which operating system do you have? For mac I usually prefer sips over convert. Can you also specify which aspects of the image you consider as poor quality? The result of convert can be tweaked with a lot of parameters, for example by setting the -density option. – samcarter_is_at_topanswers.xyz Oct 19 '18 at 10:00
  • Can you reduce your working example to a minimum working example? – samcarter_is_at_topanswers.xyz Oct 19 '18 at 10:02
  • Example works for me to produce 64x64 cm pdf EXCEPT the first page is slightly offset compared to 2nd and 3rd so may need minor tweak HOWEVER why convert since some PDF readers can flip pages in presentation mode For example SumatraPDF can page forward/back a Multipage GIF, TIFF or PDF (unfortunately NOT PNG) much like a thumb book, admittedly it will ignore a javascript time control but your usage suggests presenter controlled timing. –  Oct 19 '18 at 10:42
  • Hi @samcarter, I am using imagemagick in windows. And I have updated the sample code and the problem I observed – Eric Sun Oct 20 '18 at 13:20
  • 1
    @EricSun If standalone gives you good results, you could use it with beamer modus: \documentclass[border=5mm, convert, usenames, dvipsnames,beamer]{standalone} – samcarter_is_at_topanswers.xyz Oct 20 '18 at 15:02
  • @samcarter, this works! And after the png is generated, use convert -crop is removing all the blank areas. Seems it works for png but not pdf. So my issues are perfectly resolved. Thank you a lot. – Eric Sun Oct 20 '18 at 16:37

2 Answers2

3

The quality of a png is related to the size and aliasing of the pixels. In order to get a nominally 64 x 64 cm .png you need to use convert with a low -density 100 if you change the density to 200 it will take 4 times as long but produce a 128 cm x 128 cm output and if you double that it takes 16 times as long to produce a .png of 256 cm x 256 cm but the lines will appear much finer in comparison.

Thus it depends on your target use as to which is best. Note that in all cases these resultant png's would be unacceptable to be imported in a pdf for distribution to ISO standard as the lines would be miles too thin (Although some reader/viewers would use thickness overrides to make them appear presentable).

Many users expect magick command to behave in a uniform way however you need to add where they are to be applied so for crop you may need a more complex definition such as

convert -gravity center -density 100 -crop 2450x1800+0+0 +repage beamer.pdf images.png

where 2450x1800 is the size of image you require. Alternative command options are -chop & trim

many examples are given here http://www.imagemagick.org/Usage/crop/

[Later edit] To Illustrate the need to decide a good value such as 192 dpi here are the results from the updated sample Go DOWN THE LEFT to compare PDF to convert and capture Then see that an optimum in this case is 192 dpi for 200%-400% viewing

enter image description here

So in this case we can combine the two answers and to automatically convert all pages using a first line of

\documentclass[border=5mm,convert={density=192},usenames,dvipsnames,beamer]{standalone}
  • Hi @KJO, please see my updated example, with some text the problem is more easy to observe. I tried to use the command line you provided, but seems the generated image don't get much enhancement – Eric Sun Oct 20 '18 at 13:26
  • 1
    Updated answer per your latest updated mwe, suggests you could try convert -density 192 to get a reasonable output but your final choice may depend on line thickness and font sizes PNG is nominally 96 dpi thus multiples are best 96, 144, 192, 240, 288 etc. –  Oct 20 '18 at 15:37
  • I tried the imagemagick convert in Windows, seems the -density parameter don't take effect, no matter what numberI use, the generated png is with the same size. So maybe you are using a different convert than me – Eric Sun Oct 20 '18 at 16:55
  • Its ImageMagick 7.0.8-12 Q16 x86 from September (Portable is always the easiest to update and move around, at present its on path in my Lyx3) It has about nine copies of itself as different names for different callers but one is named convert.exe –  Oct 20 '18 at 23:16
  • I am using the same version, not sure what is the problem. I will temporarily use proposal from @samcarter to generate png directly. But thank you for all the help, giving me more understanding of the convert tool itself. – Eric Sun Oct 21 '18 at 11:42
  • For what its worth the first method is easiest to implement thus in the viewer (SumatraPDF or Acrobat ?) zoom to desired setting e.g. zoom exactly to 200 etc. (note its not the same as density) you will NOT see the final result because the viewers use anti-aliasing but if you use the same viewer to look at final .png is good (Sumatra can view/present .PNG) select ALL & copy paste to paint you can only do 1 page at a time you see the overall size is 4389^2 save each png. It is slow but gives confidence that the setting is about right. now you can try convert settings by hand to achieve similar. –  Oct 21 '18 at 11:53
  • OK I amended @samcarter 's recommended first line to include density. However that raised a question with the second sample MWE since whilst using that method, there was interference and the first page was bunched up to half width (so for that non typical mwe combo I had to add a dummy first page and discard it) BUT as it worked well with your original combination I am leaving it as it stands. –  Oct 21 '18 at 21:22
  • thank you for all the suggestions. Using convert -delay 50 -loop 0 -density 300 -trim +repage target.pdf target.gif don't have this offset problem, maybe it is the problem of pdf viewer itself? – Eric Sun Oct 22 '18 at 08:59
  • command line was good it was just that inline call got upset by something perhaps the <+-> –  Oct 22 '18 at 12:47
1

You indicate in your question that you are satisfied with the quality the standalone class gives you.

The good news is that standalone has an option beamer which allows you to use your presentation including frames and overlays with standalone. So in your example change the document class to

 \documentclass[border=5mm, convert, usenames, dvipsnames,beamer]{standalone}