\animategraphics(动画包)和具有栅格化效果的 PDF 会产生伪影

\animategraphics(动画包)和具有栅格化效果的 PDF 会产生伪影

\animategraphics使用 LaTeX Beamer 中的(包)从多页 PDF 准备 SVG 动画幻灯片时,animate我发现 PDF 中嵌入的栅格化效果存在问题,导致生成的 SVG 中出现伪影。

一个例子,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}

多页 PDF 是pdftk由 创建的多个 PDF创建的Inkscape。示例如下:http://gac.udc.es/~emilioj/all_pages.pdf

从 LaTeX 文件中,可以通过以下方式获取 xdv 文件:

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

最终生成的 SVG 如下:

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

所获得的 SVG 示例:http://gac.udc.es/~emilioj/test.svghttp://gac.udc.es/~emilioj/test.log

我在 Debian Sid 系统中使用TeX Live2020.20210202 和2.11.1,并尝试了TeX Live 中包含的软件包(2020/10/07)以及 git 的最新版本(2021/06/11)。dvisvgmanimate

答案1

更新

正如马丁在他的评论中所述,这是 PostScript 格式的限制,它不支持位图中的透明度,并且是 PDF 到 SVG 转换过程中的中间步骤。

为了解决这一限制,提出了一个 Perl 脚本,用于将嵌入位图中的黑色转换为透明色。该脚本要求嵌入位图为 PNG 格式。由于默认情况下会将dvisvgm位图内容转换为 JPEG,因此--bitmap-format=png16m必须添加选项。

Perl 脚本使用Image::MagickMIME::Base64模块。希望这两个模块都已存在于您的系统中。否则,需要安装它们。对于Image::Magick按照给出的说明进行操作这里

首先,确保位图数据嵌入为 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

然后,对输出运行脚本dvisvgm

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;
      }  
  }
}

相关内容