创建多页 PDF 动画

创建多页 PDF 动画

有哪些方法可以在乳胶中制作动画并将其转换为.mp4之类的视频格式?

答案1

创建多页 PDF 动画

创建带有动画的多页 PDF 的一种可能性是使用beamer。利用其使用叠加的功能,可以轻松创建如下例所示的图像序列:

\documentclass{beamer}

\usepackage{tikz}
\setbeamertemplate{navigation symbols}{}
\usetikzlibrary{overlay-beamer-styles}
\usepackage{tikzlings}

\begin{document}

\begin{frame}[label=jump]

    \begin{tikzpicture}[remember picture, overlay]

        \foreach \x in {0,5,...,180}{
            \only<+>{

                \begin{scope}[yshift=sin(\x)*1cm,xshift=\thepage/\insertdocumentendpage*18cm]
                    \marmot[xshift=-1.2cm,yshift=-2.8cm]
                \end{scope}

                \draw[thick] 
                    (-3.7+\thepage/\insertdocumentendpage*18, 0.6) .. controls 
                    (-3.7+\thepage/\insertdocumentendpage*18, 0.6) and 
                    (-3.5+\thepage/\insertdocumentendpage*18, -0.5) .. 
                    (-1.5+\thepage/\insertdocumentendpage*18, {sin(\x)-2});

            }
        }

        \shade[ball color=red] (-3.7+\thepage/\insertdocumentendpage*18,1.4) ellipse (0.5 and 0.9);     

    \end{tikzpicture}

\end{frame} 

\againframe{jump}
\againframe{jump}
\againframe{jump}
\againframe{jump}
\againframe{jump}

\end{document}

将多页 PDF 转换为电影

例如,要转换多页 pdf,可以使用以下 bash 脚本。它使用convert来自图像魔术师, 这Handbreak 视频转码器视频音频软件 ffmpeg

# clean up old video
rm test.mp4

# convert to png images
# is called something different in windows, `magick convert` ?
convert -density 160 test.pdf test.png

# convert to video
# modify -r 10 to adjust the speed in which the individual images are shown
# combine the video with music starting at second 16: -ss 00:00:16 -i FunnyMusic.mp3  
ffmpeg -r 10 -ss 00:00:00 -i test-%d.png -ss 00:00:16 -i FunnyMusic.mp3 -shortest test_raw.mp4

# repair video, add preview image etc.
HandBrakeCLI --crop 0:0:0:0 -i test_raw.mp4 -o test.mp4

# clean up
rm test-*.png
rm test_raw.mp4

# view :)
open test.mp4

结果

enter image description here

例子

一些动画场景的示例,大部分使用与上述相同的技术,可以在以下位置找到:https://vimeo.com/305374856

enter image description here

(源代码可从https://github.com/samcarter/Extravanganza2018

答案2

我编写了一个转换脚本,该脚本将 tikz 动画转换为 mp4 文件。它通过操纵 TeX 源来为动画的每一帧设置 tikz 的快照功能,然后让 TeX 渲染它们。然后使用 imagemagick 将输出转换为 png,最后与 fmmpeg 连接。我做了相当多的优化(并行执行 TeX 进程),我自己也用过几次。请随意查看:https://github.com/nitardus/tikz2mp4

编辑:为了以防万一,这里是该脚本的简化版本:

#! /usr/bin/perl
use v5.14;
use strict; use warnings;
use Cwd;
use File::Spec;
use File::Temp;

my $duration = 5.5; # length of your animation (in seconds);
my $fps = 25;       # frameratr
my $density = 300;  # resolution
my $texcommand = 'lualatex';
my $videolib   = 'libx264';

my $dir = getcwd();
my $tempdir = File::Temp->newdir();
my $filename = $ARGV[0] or die "You must specify a LaTex file for input!\n";
$filename =~ s/\.tex//;

# COMMAND NAMES
my @tex      = ($texcommand, '-output-directory', $tempdir);
my @convert  = ('magick', 'convert', '-background', 'white', '-alpha', 'remove',
        '-alpha', 'off', '-density', $density);
my @identify_h = ('magick', 'identify', '-ping', '-format', "'%h'");
my @identify_w = ('magick', 'identify', '-ping', '-format', "'%w'");
my @mogrify_h  = ('magick', 'mogrify', '-chop', '0x1');
my @mogrify_w  = ('magick', 'mogrify', '-chop', '1x0');
my @ffmpeg   = ('ffmpeg', '-y', '-framerate', $fps,
        '-pattern_type', 'glob', '-i', '*.png',
        '-c:v', $videolib, '-pix_fmt', 'yuv420p');

# get contents of the .tex file, prepare it
my $buffer = '';
while (<>) {
  # Skip comments and empty lines
  next if m/^\s*%/ or m/^\s*$/;
  # Add the snapshot option to the tikzpicture environment
  if    ( s! \\begin\{tikzpicture\} \s* \[
       !$&make snapshot of = ###, !x
    ) {}
  elsif ( s! \\begin\{tikzpicture\}
       !$&\[make snapshot of = ###\]!x
    ) {}
  $buffer .= $_;
}

# compute time values, add to @queue
my @queue;
for my $sec (0..int ($duration - 1)) {
  for my $frac (0..($fps - 1)) {
    my $time = $frac / $fps + $sec;
    push @queue, "$time" . "s";
  }
}
push @queue, ( int $duration ) . 's';

# make list of output filenames
my $width = length scalar @queue;
my @filenames;
for my $number  (0..$#queue) {
  my $format = "%0$width" . "d-$filename";
  my $name = sprintf $format, $number;
  push @filenames, "$name";
}

for my $frm (0..$#queue) {
  say STDERR "Rendering frame for: $queue[$frm]";
  my $buf = $buffer =~ s/###/$queue[$frm]/gr;
  my $texinput = File::Spec->catfile($tempdir, "$filenames[$frm].tex");
  open my $tex_fh, '>', $texinput
    or die "Cannot open $filenames[$frm].tex for.write: $!\n";
  print { $tex_fh } $buf;
  close $tex_fh;
  !system @tex, $texinput
    or die "LATEX ERROR while processing frame $filenames[$frm]!";;
  unlink "$filenames[$frm].tex";

  # RUN IMAGEMAGICK
  my $pdf_file = File::Spec->catfile($tempdir, "$filenames[$frm].pdf");
  my $png_file = File::Spec->catfile($tempdir, "$filenames[$frm].png");
  # convert pdf to png; die on non-zero exit value
  !system @convert, $pdf_file, $png_file
    or die "IMAGEMAGICK ERROR while processing frame $filenames[$frm]!";
  # chop one row of pixels if the height is odd
  my $height = `@identify_h $png_file`;
  my $width  = `@identify_w $png_file`;
  system @mogrify_h, $png_file if $height % 2;
  system @mogrify_w, $png_file if $width  % 2;
}

chdir $tempdir;
my $output_file = File::Spec->catfile($dir, "$filename.mp4");
system @ffmpeg, $output_file;
unlink glob "*$filename.*";
chdir $dir;
unlink $tempdir;

确保已安装 imagemagick 和 ffmpeg,将此脚本放在一个文件中(例如 tikz2mp4),然后在 .tex 文件(例如 example.tex)上使用以下命令执行它

perl tikz2mp4

这里例如(来源修改自官方 tikz 动画文档

相关内容