有哪些方法可以在乳胶中制作动画并将其转换为.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
结果
例子
一些动画场景的示例,大部分使用与上述相同的技术,可以在以下位置找到:https://vimeo.com/305374856
答案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 动画文档。