1

Preparing a SVG animated slide from a multi-page PDF with \animategraphics (animate package) in LaTeX Beamer I find issues with the rasterized effects embedded in the PDF, resulting in artifacts in the resulting SVG.

An example, test.tex:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                                    
% Force graphicx/color driver `dvips.def'                                      
\RequirePackage[dvips]{xcolor}                                                 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\documentclass[dvisvgm,aspectratio=169]{beamer}
\setbeamertemplate{navigation symbols}{}

\usepackage{animate}
%\usepackage{graphicx}
%\usepackage{tikz}

\graphicspath{{./}}

\title{Test}
\subtitle{TL;DR}

\begin{document}

\begin{frame}{}

\animategraphics[controls,loop,autoplay,width=.8\linewidth]{1}{all_pages}{}{}

\end{frame}

\end{document}

The multi-page PDF was created with pdftk from multiple PDFs created with Inkscape. An example can be found here: http://gac.udc.es/~emilioj/all_pages.pdf

From the LaTeX file a xdv file is obtained by:

xelatex --no-pdf test.tex
xelatex --no-pdf test.tex

and the final SVG is generated with:

dvisvgm --zoom=-1 --font-format=woff2 --page=- --bbox=papersize test.xdv

An example of the obtained SVG: http://gac.udc.es/~emilioj/test.svg (http://gac.udc.es/~emilioj/test.log)

I am using TeX Live 2020.20210202 and dvisvgm 2.11.1 in a Debian Sid system and I tried the animate package included in my TeX Live (2020/10/07) as well the last release from git (2021/06/11).

  • probably not related but why do you force dvips for the colors if you use xelatex? – Ulrike Fischer Jul 19 '21 at 11:19
  • Hi! It is definitely a good question! That is a workaround as xcolor is not dvisvgm aware: https://tex.stackexchange.com/a/537711/212085 – Emilio J. Padrón Jul 19 '21 at 12:30
  • 2
    ah, well with a current latex you could try \makeatletter \declare@file@substitution{xetex.def}{dvisvgm.def} \makeatother , this will force xetex to load the dvisvgm.def instead (but I don't know if the driver is better for your use case). – Ulrike Fischer Jul 19 '21 at 12:55

1 Answers1

2

UPDATE

As Martin states in his comment, this is a limitation of the PostScript format, which does not support transparency in bitmaps and which is an intermediate step during PDF to SVG conversion.

To work around this limitation, a Perl script is proposed that converts black colour to transparency in embedded bitmaps. The script requires embedded bitmaps to be in PNG format. Since, by default, dvisvgm converts bitmapped content into JPEG, option --bitmap-format=png16m must be added.

The Perl script makes use of the Image::Magick and MIME::Base64 modules. Hopefully both are already present on your system. Otherwise, they need to be installed. For Image::Magick follow the instructions given here.

First of all, make sure bitmap data are embedded as PNG:

latex test.tex # or xelatex --no-pdf test.tex
dvisvgm --zoom=-1 --font-format=woff2 --page=- --bbox=papersize --bitmap-format=png16m test.dvi # or test.xdv

Then, run the script on the dvisvgm output:

svgtransparency.pl test.svg > test-fixed.svg

#!/usr/bin/perl -w

#######################################################################

converts black colour in embedded PNG data to transparent in SVG

fixes transparency issue reported in

https://tex.stackexchange.com/questions/605587

usage:

dvisvgm --zoom=-1 --font-format=woff2 --page=- --bbox=papersize --bitmap-format=png16m test.dvi

svgtransparency.pl test.svg > test-fixed.svg

#######################################################################

use MIME::Base64; use Image::Magick;

$ispng=0; $pngdata=''; $image=Image::Magick->new(magick=>'png');

while(<>){ print unless ($ispng); if (/data:image/png;base64,$/) {$ispng=1;next;} if ($ispng) { $pngdata .= (/^(.*?)('/>)?$/)[0]; if (/'/>$/){ $pngdata=decode_base64($pngdata); $image->BlobToImage($pngdata); $image->Transparent(color=>'black'); $pngdata=($image->ImageToBlob())[0]; $pngdata=encode_base64($pngdata); print "$pngdata'/>\n"; @$image=(); $pngdata=''; $ispng=0; }
} }

AlexG
  • 54,894
  • Thanks a lot for reviewing the issue @AlexG! – Emilio J. Padrón Jul 19 '21 at 14:24
  • 1
    Wait, I am going to prepare a Perl-script to convert black to transparency. Give me a few minutes. – AlexG Jul 19 '21 at 14:32
  • 2
    That's a limitation of PostScript which doesn't support alpha channels in image data. So, PS images are always opaque. Since dvisvgm's PDF support relies on Ghostscript that in turn internally converts PDF to PS, dvisvgm has no access to any transparency information when extracting the bitmap data. Unfortunately, there isn't much I can do here. – Martin Jul 19 '21 at 14:48
  • 1
    No problem, this can be done in a post-processing step. And thank you for your input! – AlexG Jul 19 '21 at 14:52
  • 1
    Thank you very much @AlexG for your kind help! Your perl script works like a champ postprocessing the transparencies in the final SVG :-) Really appreciate it! – Emilio J. Padrón Jul 20 '21 at 13:17