65.9K
CodeProject 正在变化。 阅读更多。
Home

动画编辑器 - 为您单调的 Covid 世界带来卡通色彩

starIconstarIconstarIconstarIconstarIcon

5.00/5 (6投票s)

2020年7月16日

CPOL

36分钟阅读

viewsIcon

12319

downloadIcon

208

使用此动画编辑器将您自己的精灵与任何您选择的 MP4 结合

引言

电影《谁陷害了兔子罗杰》中的场景。多亏了这部好莱坞杰作,我们挚爱且色彩斑斓的朋友们再也不必像以前那样,在偏僻的卡通城贫民区中被妖魔化和边缘化了。

如果有人没有将谁陷害了兔子罗杰列入那些不仅改变了行业,而且彻底改变了卡通人物在我们社区中被接受方式的开创性电影名单中,那么他们就从未看过谁陷害了兔子罗杰。这是可以原谅的,我理解,不是每个人都拥有影迷的基因,能够帮助他们辨别现代世界中更精致的体验。但即使你以前从未见过卡通人物在我们中间行走,现在你也可以了。只需看看这个视频,看看一只醉酒的维尼熊试图在我家惹麻烦时会发生什么。(他们可能都不是反派,但有时他们可以是混蛋)。

动画编辑器的屏幕截图

过去几个月里,制作卡通视频让我忙得不可开交,同时我还在微调这个项目。还有很多事情没有完成,但我现在正处于项目的十字路口,它已经足够稳定和功能齐全,可以让任何人制作视频,所以我感到我必须停下来并发布我现有的内容,然后再继续为它实现更新、更棒的口哨、小工具和部件。

我最近的项目包括:

  1. Covid-19 洗手信息短片,这个视频大约花了一周时间在四月份完成,当时这个应用程序还处于初期阶段,令我惊讶的是,尽管当时动画编辑器存在所有问题,我还是设法将这个视频制作了出来。这是我第一次尝试实时视频/动画创作。你可以看到声音有点不协调,视频动作也很卡顿。
  2. 维尼熊,尽管源视频的光线很差,演员动作也很卡顿——这个视频仍然让我发笑。
  3. 虫子和米奇是一个更简单的项目——没有太多真人演员动作,但卡顿感仍然存在。而且,我必须承认,我在制作兔八哥/米老鼠精灵时有点偷懒。
  4. 俯卧撑,我就是喜欢这首歌的音乐——谁不喜欢好波尔卡舞呢?虽然还是很卡顿。
  5. UFC 的罗斯·纳马朱纳斯,我还能接受看自己制作的颗粒感、卡顿的视频……但罗斯·纳马朱纳斯不行。这简直不可接受。所以在那时,我花了一个月的时间来改进视频捕捉方式,使用时间戳确保所有帧都在正确的时间绘制。将所有帧图像录制到文件中,然后再通过从硬盘上提取每个最终屏幕图像并按照精确的时间戳计划将其呈现在屏幕上,从而将所有内容捕捉成视频……尽管一路经历了许多失败,但还是取得了显著的改进。
  6. 维尼熊遇见贝蒂娃娃——最后,在前一个视频中制作了“玫瑰爆发”并对项目进行了许多修改之后,我不得不制作另一个涉及实际精灵的视频,以确保一切正常运行……两周后,我们做到了。

加载一个示例项目

你可以在这里下载制作维尼熊遇见贝蒂娃娃视频所需的所有文件(你需要将整个 zip 文件解压到你的 `c:\` 驱动器上的一个新目录中,你需要创建 `c:\AnimationEditor`,这样当你加载 `Winnie Meets Betty Boop.xml` 文件时,它才能正常运行)。下图显示了需要创建的目录以及 `.xml` 项目文件要加载和正常工作所需的文件位置。

你可以看到,在上面工作目录的图片中,有两个文件带有 `.bin` 文件扩展名。这两个文件都是帧图像的二进制流以及与之关联的时间戳。第一个文件是动画编辑器在 `WindowsMediaPlayer` 上播放源 MP4 视频,并在播放时截取视频屏幕,然后将这些图像存储到 `Winnie Meets Betty Boop half speed.bin` 文件(以其采样的 MP4 命名)的结果。另一个 `.bin` 文件是视频的最终录制,它通过使用第一个 `.bin` 文件中的源图像,并在这些图像上绘制所有必要的精灵,然后将它们存储在单独的 `Winnie Meets Betty Boop_record.bin` 中,该文件以项目名称命名。

MP4文件如下:

  1. Winnie Meets Betty Boop SOURCE.MP4 - 这是用我的手机录制的未编辑文件
  2. Winnie Meets Betty Boop AUDIO.MP4 - 这是已编辑的音频文件(仍然是MP4,仅用于其音频)
  3. Winnie Meets Betty Boop half speed.MP4 - 音频文件减慢到半速
  4. Winnie Meets Betty Boop Screen Capture.MP4 - 这是项目中的 `WinnieMeetsBettyBoop_record.bin` 文件以两倍速度播放并使用第三方视频屏幕录制应用程序捕捉的录像。

这个 `.vProj` 文件是使用 VSDC 的视频编辑器生成的,用于生成最终结果。

除了所有这些文件,你只需要担心维尼和贝蒂的两个精灵文件,以及动画编辑器用来跟踪项目的所有重要 `.xml` 文件。

总体概述

动画编辑器使用的整个过程在俗语中通常被称为“完全的黑客行为”。因为没有简单的方法可以使用 C# 编辑/访问/读取 MP4 中的单个图像(我找遍了,一无所获,如果有一种方法,我很乐意知道),所以将 MP4 视频分解为单独的可操作图像有点像摔跤。以下是动画编辑器工作方式的总体概述。

制作视频涉及几个步骤:

  1. 需要一个源视频——用相机自己录制一个,或者下载你喜欢的视频
  2. 最好是源视频的长度与输出视频的长度完全相同,这样你就可以在最终产品中使用其音频。将其保存为你的音频文件(或者不保存,随你喜欢)。
  3. 有了这个音频文件后,你可以通过将源文件放慢到半速或四分之一速并将其另存为单独的文件(不破坏你的音频文件)来提高输出视频的质量。你可以使用免费的第三方软件来编辑视频。VSDC 是一个非常好的产品,他们提供了一套工具。
  4. 然后,动画编辑器在 `WindowsMediaPlayer` 上播放 MP4 视频,并尽可能多地录制帧。更好的硬件会带来更好的结果。我的笔记本电脑足够用,但游戏 PC 会更好。
  5. 现在,动画编辑器在硬盘上有一个二进制流文件,其中包含它在上一步中捕获的图像序列,每个帧都有一个时间戳。然后处理这些帧,使每个时间戳减去其前一个时间戳,并将差值与该图像关联起来。这样,每个帧都有一个时间戳,告诉动画师在绘制一帧之后需要等待多长时间才能绘制下一帧。当这些帧被随机播放、复制或当帧序列在编辑过程中被用户更改时,它们会随身携带各自的延迟时间。
  6. 用户使用 动画编辑器 的工具向视频中添加精灵,直到视频小精灵编辑完成。
  7. 动画编辑器然后绘制并定位所有小精灵,生成最终的图像序列,并将其记录在单独的二进制流“..._record.bin”文件中。
  8. 当你准备好使用第三方视频屏幕捕捉应用程序并生成项目 MP4 文件时,使用上下文菜单“场景->播放-设置速度”选项(如果你正在处理半速源视频 -> 将录制速度加倍,或者四分之一速时将其设置为 4.0)来设置录制视频的播放速度以抵消源视频的速度。使用你的第三方应用程序录制电脑屏幕,并告诉动画编辑器以你设置的速度播放项目的录制版本。这将生成你项目的 MP4 视频。
  9. 使用你在步骤 8 中刚录制的屏幕视频捕捉,并使用你用来创建音频文件和半速视频的视频编辑器进行最终编辑。包含你的音频文件中的声音,添加你认为最好的标题,然后让片尾字幕滚动。

你得到的结果将取决于你的硬件(以及你的创造力)。我正在用一台笔记本电脑工作,在半速源视频下得到了不错的结果,但如果你有一台更快的机器,你可以做得更好。输出 `_record.bin` 文件中每个帧的时间戳与你原始源视频 `.bin` 文件的时间戳不同之处在于,原始文件在每帧之间保持一个延迟时间并附加到每帧上,而 `_record.bin` 文件则跟踪自视频开始以来的时间,因此在播放最终项目时没有累积误差。此外,`_record.bin` 文件每个帧有两个时间戳。第一个等同于 MP4 最初转换为二进制流时记录的原始延迟时间(无论时间线编辑过程中创建的任何用户变体,累积的帧延迟都用作记录文件的时间戳),另一个时间戳是第一个时间戳乘以你使用上述上下文菜单的“场景->播放-设置速度”选项设置的播放速度的产物。由于更改后的速度作为时间戳直接写入文件,在你告诉编辑器播放你的动画之前,速度设置不必是 2 的倍数(程序员可能会倾向于假设内部二进制寄存器移位目的,因为你的计算机可以非常快速地乘以和除以 2)。最终播放速度的时间戳相对于源视频进行更改,并在动画编辑器播放录制之前设置。因此,在播放过程中不会即时进行任何数学运算,所有帧都已对齐,准备好与单个开始时间进行比较,然后再将下一帧显示在屏幕上。这样,你的动画播放只需要将第一张图像显示在屏幕上,然后执行无操作循环,同时将下一个加载的视频帧的时间戳与当前时间进行比较,并在时间流逝后将下一张图像显示在屏幕上,从二进制流中加载后续帧,然后再次执行。

使用动画编辑器

:下文提及且视频中仅简要提及的“小精灵绘制序列”在影片拍摄时实际上称为“精灵绘制序列”。这种严重不当的错误和不遵守可接受社会礼仪的正常标准,严重损害了作者对代码体面的认知,为此他真心表示歉意。请接受视频中对臭名昭著的绘制小精灵序列列表的错误标记是由于睡眠不足而导致的判断失误。谢谢。

观看关于此项目的简短 YouTube 视频。

你首先需要熟悉我在上一篇文章中介绍的classSprite。你不需要阅读该系列的所有文章,但你需要熟悉精灵编辑器 2017 - 构建和编辑动画这篇文章,并了解如何使用精灵,以便最大限度地利用动画编辑器

绘制并准备好你的精灵后,加载动画编辑器。

步骤 1:将 MP4 加载到动画编辑器中

加载 MP4

将鼠标光标移到屏幕底部的时间线上。右键单击鼠标,调出附属于时间线的上下文菜单,然后选择“加载->MP4”,如上图所示。动画编辑器会将你选择的 MP4 文件加载到 `WindowsMediaPlayer` 中并播放视频。然后它会以最快的速度截取你的电脑屏幕,直到视频播放完成。由于动画编辑器需要全身心投入,并且你的项目结果取决于机器在此操作中的最佳利用,因此最好在继续之前停止运行所有其他应用程序。关闭 WiFi,这样你的 Windows 操作系统就不会选择在这个时候进行升级。然后让它开始工作吧。

此操作完成后,你将需要处理两个时间线……这没关系。

“时间线”就是“时间线”,它之所以被称为“时间线”是有原因的。原因就是……因为它就是你项目的时间线。

尽管其他时间线(请小写)也是时间线,但它们并不是你要绘制小精灵的时间线。如果你还没注意到,你可以用鼠标滚轮在任何时间线上放大/缩小。点击任何时间线,你就会在屏幕上看到图像。你可以使用鼠标选择多个帧并观看这些帧的循环,然后,使用右键鼠标的上下文菜单,你可以像任何编辑器一样进行剪切、复制和粘贴。这些时间线实际上只是一系列索引,指向你正在使用的 `.bin` 文件中共同的图像列表。即使你更改了整个时间线,你实际上也没有更改 `.bin` 文件。你只是打乱了指向 `.bin` 文件中帧的索引序列,但 `.bin` 文件保持不变,只有存储在你项目 `.xml` 文件中的数据被更改。你可以查看动画编辑器任何已保存项目的 `.xml` 文件(如下图所示),看到时间线中的时间帧都有一个文件路径和一个索引,这个数字指的是该文件中 `.bin` 帧的索引。你的项目引用的所有 `.bin` 文件必须位于它们最初加载时的位置,否则你的项目将无法正确加载。你实际上不需要了解所有这些就能使用动画编辑器。只需记住,你在此处对输出视频时间线所做的任何更改都不会反映你之前保存的音频文件……无论你是否想更改源视频的帧序列,这实际上只取决于你打算做什么,但请记住,如果你计划使用原始视频的音频,你需要保持时间线完整。

所以,选择底部时间线(在你给它新名称之前一直命名为默认)中的所有帧并复制。然后点击它上面的时间线,通过上下文菜单选择“粘贴”。

完成此操作后,你项目的“时间线”中将准备好原始视频,等待绘制。

步骤 2:创建小精灵

如果你读过我的文章精灵编辑器 2017 - 构建和编辑动画,你就会知道什么是精灵。我从维基百科得到的定义是:“在计算机图形学中,精灵是一个二维位图,它被整合到一个更大的场景中,最常见于 2D 视频游戏……”它继续说下去,但这就是它的要点。只不过,在动画编辑器中,你可以同时在屏幕上显示几个不同的生物(例如,动画卡通),每个生物在技术上都是一个精灵,但是,假设你想要一个《达菲鸭》的哈哈镜场景或《火星人马文》的克隆剧集,那么你需要在屏幕上绘制相同精灵的几个不同版本。`classSprite` 的单个实例会为你完成这项工作,但你需要跟踪屏幕上所有不同的克隆。每个图像都需要有自己的大小、角度、位置、动画、动画帧等值,适用于每个视频帧(此信息存储在一个名为 `classPixieFrame` 的类中)。因此,当指代相同角色的这些不同图像时,动画编辑器将它们称为“小精灵”(Pixies),而不是“精灵”(Sprite)。在民间传说中,小精灵精灵仙女非常相似。在计算机科学中,有一种东西叫做Pixie 渲染器,它显然是“由德克萨斯大学奥斯汀分校计算机科学系的 Okan Arikan 开发的用于生成逼真图像的照片级真实感光线追踪渲染器”。然而,在动画编辑器中,它完全不是一回事。我只是需要一种方法来描述正在发生的事情,而不会在指的是小精灵时混淆精灵。也许以后,我会想出使用“仙女”一词的理由,但我们还没到那一步。

所以,屏幕上的每个角色都是一个使用精灵类实例绘制的小精灵。

小精灵在其中绘制的每个时间帧都将包含在该时间帧的屏幕上绘制该小精灵所需的信息。该信息位于名为 `classPixieFrame` 的类中。每个小精灵都指向 `classSprite` 的一个实例,该实例告诉动画师当你指定该精灵的角度、动画和动画帧时,应将哪个图像放在屏幕上。你可以拥有任意数量的精灵,但你只需要任何给定精灵的一个实例,即可在项目中包含任意数量的具有相同精灵图像的小精灵。如果这是你的喜好,你可以在屏幕上显示十几个唐老鸭。尽管每个唐老鸭都是一个独立的小精灵,但它们都将使用唐老鸭精灵类的同一实例进行绘制。

清楚了吗?……你会习惯这个想法的。

要创建一个小精灵,你只需点击场景编辑器顶部、小精灵组合框旁边的“小精灵”按钮,然后从鼠标下方弹出的上下文菜单中选择“新建”。会出现一个表单,要求你输入新小精灵的名称,只需输入你想要的名称并点击“确定”即可。此时,场景编辑器的外观会略微改变。小精灵组合框会变成红色,通常这是一个不好的迹象,但在这里它只表示这个新的小精灵还没有被分配精灵。为了帮助你为小精灵选择一个精灵,“精灵列表”会被带到前面,并绘制在“小精灵绘制序列”列表的上方,如下图所示。

如果你想附加到此小精灵的精灵尚未出现在你的列表中,你必须从硬盘加载它(或者,如果那是你正在寻找的,则创建一个文本精灵)。只需点击蓝色精灵列表区域的“新建”按钮,然后加载你需要的精灵。一旦精灵被添加到加载到内存中的可用精灵列表,双击它就会将其绑定到上方组合框中当前选定的小精灵。

注意:请注意,如果你尝试绘制新精灵无法识别的动画或动画帧,更改小精灵的精灵可能会导致动画编辑器崩溃。

注意:当您加载现有项目时,尽管小精灵组合框可能已为您选择了一个小精灵供您使用,但您需要在开始之前使用组合框确认此选择。这仅在您首次加载 `.xml` 项目文件或创建新小精灵时适用,并且在这两种事件发生后只需执行一次。如果您不点击小精灵组合框确认您的选择,下面的路径编辑器界面可能无法正常运行。我知道这是一个错误,但它相对较小,您现在只能忍受它。

为新小精灵命名并分配精灵后,你就可以开始了,可以将“精灵列表”推回“小精灵绘制序列”后面的隐藏位置,你很快就会用到它。

步骤 3:生成路径

每个小精灵都与一个精灵绑定。

精灵类的每个实例都包含一个或多个精灵动画。

每个精灵动画都包含一个或多个精灵动画帧。

然而,你的小精灵在它出现的每个视频帧上的屏幕外观,不仅由它的精灵精灵动画精灵动画帧描述,还由它的大小角度位置描述。

所有这些信息,对于它出现的每个视频帧,都存储在小精灵的PixieFrame中。

项目时间线中的每个视频时间帧(如 XML 文件所示)都有一个 PixieFrame 列表,描述了每个时间帧中的所有小精灵。

要编辑任何小精灵在任何给定视频时间帧中的 PixieFrame,你可以使用“帧编辑器”界面。

  1. 选择要编辑的视频时间帧(可以通过鼠标滚轮在主屏幕上滚动、使用时间线跳转到所需帧,或使用主屏幕上下文菜单的“帧”选项)。
  2. 从上方的小精灵组合框中选择一个已在指定时间帧中绘制的小精灵。
  3. 使用“帧编辑器”界面更改你想要的值。

但这只有在你处理的小精灵在时间线的选定视频时间帧中已经有一个 PixieFrame 时才能发生。

这就是路径编辑器发挥作用的地方。

动画编辑器 的上下文中,路径是一种为项目时间线中的一系列视频时间帧生成小精灵帧的方法。你设置所需的变量(位置、大小和角度的开始/结束值,以及选定的精灵动画和精灵动画帧),然后点击“生成帧”。

要做到这一点,你必须:

  1. 确保你已选择正确的小精灵(再次点击组合框以确认)
  2. 设置起始帧
  3. 选择一个精灵动画
  4. 选择一个起始精灵动画帧索引(默认为 0)
  5. 选择结束帧,使其与精灵动画的结束相对应(我通常使用比完整动画少一帧,效果很好),或者根据需要循环播放同一动画,直到达到项目时间线中的特定视频时间帧
  6. 有两个方便的功能叫做:“跟随上一个”和“先行下一个”。这两个功能在路径编辑器中都有各自的按钮,它们允许你在动画之间无缝过渡,而无需重新定位、调整大小或设置精灵的角度,以便该路径的起点将精确匹配前一个路径中相同小精灵的大小、角度和位置(同时还要考虑路径两端的 `UseRelativeTo` 肢体)。它们的名称不言自明,可以区分它们之间的差异,但你必须确保在使用“跟随上一个”选项之前正确设置路径的起始帧,同样,在使用“先行下一个”功能之前必须设置结束帧值。
  7. 设置小精灵起始帧和结束帧的角度和大小。你可以通过点击下方描述的“pt Start”和“pt End”按钮来查看这些更改的结果,并在步骤 7、8 和 9 之间循环切换,直到你对小精灵的起始/结束角度、大小和位置满意为止。
  8. 设置路径的角度增量(小精灵新路径长度上的角度变化),你的小精灵将在起始帧和结束帧之间旋转任意度数
  9. 如果您需要设置小精灵的起始/结束位置,可以通过多种方式进行。pt Startpt End 按钮允许您使用鼠标光标将小精灵定位到屏幕上的任何位置。当您使用鼠标将小精灵定位到屏幕上时,视频图像将被重新调整大小,并且屏幕上会出现一个红色矩形框。红色矩形框指示重新调整大小的图像中屏幕的结束位置,以便您可以将小精灵的起始/结束位置放置在可见屏幕的边界之外,并让小精灵随意进入/退出帧。
  10. 点击“设置字段”按钮,提示你希望路径更改的字段列表(通常,在熟悉动画编辑器并确定你只希望更改选定小精灵的 TimeFrames PixieFrame 值的某些部分之前,请勾选所有选项)。
  11. 当你对所选内容满意时,点击“生成帧”按钮,然后循环查看路径以查看结果。你可以对路径进行更改并重复操作,次数不限,但应记住经常保存项目,以防动画编辑器生气并决定罢工(劳资谈判正在进行中,但软件工会代表坚持要求更好的退休选择,而不是强制代码重用……罢工行动不太可能发生,但在项目仍在开发中时可能会发生。如果你的当地工会走上纠察线并罢工,你至少会有你项目的蓝图,并且可以随时强迫他们复工)。

4. 小精灵绘制序列

尽管项目时间线中的每个时间帧都包含屏幕上出现的每个小精灵的 PixieFrames 列表,但该 PixieFrames 列表是通过在任何给定时间帧上一次向动画添加一个 Pixie 而生成的,但它并没有告诉动画编辑器以什么顺序绘制它们。所以你需要告诉动画编辑器你希望以什么顺序绘制这些小精灵。这类似于精灵本身由精灵类绘制的方式,其中每个动画帧将精灵肢体的列表整理在一起,并且只有在它弄清楚每个肢体的位置之后,它才开始按照该动画帧特定的绘制序列绘制它们。通过在精灵类和动画编辑器中都这样做,你可以决定哪些图像出现在其他图像的前面或后面。在精灵类中,首先绘制离相机最远的手臂的角色轮廓是很重要的,这样它就会被同一角色的其他肢体和胸部等部分部分覆盖。因此,在这里你也可以选择设置一个特定的顺序,以便在任何给定时间帧图像上绘制你的小精灵,以便可见动作能更好地讲述你想要表达的故事。因此,我们现在就到了被称为“小精灵绘制序列”的部分。小精灵绘制序列本身相对简单,任何出现在给定帧中的小精灵都有一个 PixieFrame,并且它本身被包含在小精灵绘制序列的某个位置。要更改此绘制序列的顺序,你只需使用鼠标选择绘制序列中的一个小精灵,然后用鼠标滚轮向上或向下滚动,具体取决于你希望它在屏幕上显示的位置。

然而,如果你看下面的图片,你会注意到 Obelix 用他最喜欢的勒喉技术制服了两个罗马人。所以,如果我们要用(旧的——直到两周前最近的文章更新)`Sprite class` 来绘制这个场景,你将很难处理这些精灵,并且必须想尽办法让 Obelix 的身体在两个罗马人后面,同时将 Obelix 的手臂画在这两个罗马人前面。要做到这一点,你可以将他的手臂拆分成两个独立的精灵,并计算出它们应该出现的位置,或者,你可以将罗马人变成连接在 Obelix 身上且可以在任何给定精灵动画帧的绘制序列中绘制在他手臂后面的“肢体”。无论哪种情况,这都是一件麻烦事。

所以,我看了看,决定我需要做些什么,并提出了一个快速简单的解决方案。`Sprite Class` 的 `Draw_Animation_Frame()` 现在有一个重载,允许你指定一个与身体其余部分分开绘制的肢体列表。

该函数然后:

  1. 创建一个包含所有精灵肢体的新列表。
  2. 然后它创建了附着在调用函数指定精灵肢体上的肢体子列表,并将其从第一个通用肢体列表中移除。
  3. 当它拥有与调用函数指定的肢体数量相同的子列表时,它会组装精灵并准备好绘制它
  4. 它没有将整个精灵绘制到单个位图上,而是将每个列表的肢体精确地绘制到它们在正常完成的精灵位图上的位置,但却绘制到与包含所有精灵肢体的位图大小相同的单独位图上。
  5. 然后它以调用函数指定肢体的相同顺序将所有这些位图返回给调用函数。

因此,本质上,在 Obelix 的情况下,你会告诉 `classSprite` 你需要三张图像才能绘制我们下面看到的内容:一张没有手臂的身体,两张是手臂本身。为此,你会创建一个包含三个肢体的列表:`LeftShoulder`、`RightShoulder` 和 `MasterLimb`。因此,所有附着在 `LeftArm`(`leftForearm` 和 `LeftHand`)上的肢体都将绘制在单独的位图上,精确地出现在完整的精灵位图中的位置。同样,当你将 `RightArm` 包含在调用函数发送的列表中时,`rightArm`、`rightForearm` 和 `RightHand` 也将如此。最后,身体和所有未附着在指定肢体(左/右手臂)上的肢体将被绘制到第三个位图上,然后所有三个位图都将以列表形式发送回调用函数。它们的大小都相同,你只需计算第一个应该在哪里,你就知道所有它们都应该在哪里。有了这些,你绘制 Obelix,绘制罗马人,然后绘制 Obelix 的手臂,你就完成了。

如果你有机会观看维尼熊遇见贝蒂娃娃的视频,你会注意到维尼被打得鼻青脸肿。别担心,他活该,贝蒂在他得意忘形之前让他跑了。有很多方法可以绘制维尼熊的黑眼圈。最简单的方法可能是在某些特定的动画中只画他有黑眼圈,或者制作两倍于所需动画数量的动画,其中一半显示黑眼圈,另一半不显示。但是,我们没有这样做,所有维尼的动画都把他画成有黑眼圈(除了一个涉及某个中指的动画,那个中指引发了麻烦)。

看下面的图片

在这里,你可以看到《维尼熊遇见贝蒂娃娃》视频的两个时间帧序列。在第一个序列中,你会注意到“黑眼圈”在小精灵绘制序列中首先绘制(在维尼肿胀的头部后面),而在第二个序列中,“黑眼圈”在维尼受伤的自尊之后绘制。你可能会说,绘制一个与维尼大小相同的额外位图确实会降低速度,你是对的,但由于我稍后会解释的原因……这真的不重要。这是一个创建动画视频的快速解决方案(与速度至关重要的视频游戏不同),在这里我们可以奢侈地在自己的甜蜜时间里创建我们想要的所有图像,因此可以采取捷径来获得我们想要的结果。维尼一直都有黑眼圈,他只是以为自己可以把它藏在右耳后面而已。

执行此操作的界面并不难。在小精灵绘制序列中选择一个小精灵,然后使用鼠标右键调出其上下文菜单。你将获得三个选项:

  1. 删除主肢体(删除此帧的整个小精灵)
  2. 删除系列主肢体(删除一系列时间帧中的整个小精灵)
  3. 单独绘制肢体(这将为你提供一个肢体列表供选择)

当你选择了要单独绘制的肢体后,只需按照你想要的任何顺序设置小精灵绘制序列,即可获得所需的效果。

5. 录制视频

当您点击“场景编辑器”顶部“文件”按钮下方的“场景”按钮时,您将获得播放“动画”或“录制”项目的选项。任一选择都将在视频屏幕上显示您绘制的帧序列。然而,当您只是运行动画时,动画编辑器正在从头开始重新创建每个时间帧。它加载背景源图像以及项目中特定时间帧的所有 PixieFrame 信息,然后它根据每个小精灵的 PixieFrame 中描述的小精灵位置、大小和角度绘制各种小精灵及其精灵,完成所有这些工作后,它将图像显示在屏幕上。动画编辑器将尝试根据附加到每个背景视频帧的延迟时间来安排每个帧,但它可能需要更多时间来绘制动画,而不是平滑视频播放所需的延迟时间。为了解决这个问题,动画编辑器为您提供了一个选项,可以生成所有图像并将其存储到硬盘上的单独“_record.bin”文件中,以及每个帧的时间戳,您可以修改时间戳以加快或减慢您的最终项目。由于在播放期间,动画编辑器只需从硬盘加载单个图像(它通常会这样做,以便在绘制所有精灵之前从源 `.bin` 文件加载背景视频帧)并将其显示在屏幕上而无需执行任何工作,因此可以实现更流畅的动画。此外,由于每个 `_record.bin` 文件帧的时间戳不反映两个并列帧之间的延迟时间,而是反映动画播放开始以来的延迟时间,因此当您从一个帧到下一个帧测量时间时,不会出现累积误差。您项目的最终播放版本应该运行得更加流畅,特别是如果它涉及在屏幕上随时绘制许多大型复杂精灵图像。

在录制项目之前,你可能需要先使用上下文菜单的“切换视图”->“”->“帧索引”和“切换视图”->“”->“帧时间戳”选项来移除通常打印在视频屏幕右下角的时间帧索引和时间戳信息。

当你准备录制时,点击顶部的“场景”按钮,然后从出现的菜单选项中选择“录制”。动画编辑器将遍历所有时间帧,并使用你在编辑项目时创建的 PixieFrame 信息在每个帧上绘制所有小精灵。当动画编辑器完成此工作后,项目的工作目录中将创建一个新文件,当你再次点击“场景”按钮时,该文件将被检测到,并为你提供“播放”项目或“播放 - 设置速度”的选项。点击“播放”观看你的动画。

如果你的源视频中有真人演员,并且你为了在项目开始时加载 MP4 阶段提高性能而加长了源背景视频,那么你会希望加快录制速度,以便生成一个与源音频文件以相同速度运行的流畅视频动画。这样,你就可以在你的动画上叠加音频文件,并将原始音轨与你的动画项目匹配,然后使用你的第三方视频编辑器添加乐一通音效。如前所述,录制项目每个帧都有两个时间戳。第一个时间戳在你再次编辑背景视频序列并录制项目之前不会改变。首次录制项目后,这两个时间戳是相同的,但你可以通过使用视频屏幕上下文菜单的“场景->播放设置速度”选项来更改第二个时间戳,该选项会将你在此处输入的速度值乘以每个帧的第一个时间戳,从而生成同一帧的第二个时间戳。在播放过程中,录制动画的开始时间将与每个帧更改后的时间戳进行比较,以确保你的视频像被捕捉时一样流畅运行,并以你设置的任何速度运行,只要你的硬件能够跟上。如果你的计算机无法足够快地从硬盘加载图像并将其显示在屏幕上以跟上速度,那么将此值设置得太高是没有意义的。此操作仍然依赖于硬件,并且不会丢帧,因此最终输出将取决于你的计算机处理速度和硬盘访问速度。

一旦你对你的动画感到满意,你将不得不使用第三方视频屏幕捕捉应用程序来屏幕捕捉你的动画并将其保存为 MP4。当你这样做时,你必须在启动动画录制之前启动视频屏幕捕捉应用程序,然后等待录制播放完毕,然后才能停止视频屏幕捕捉。因此,生成的 MP4 将需要编辑以剪掉此操作的前后部分,然后你才能成功叠加你的源音轨。

代码

我于2020年3月31日启动了这个项目。当时我们在加拿大新不伦瑞克刚刚开始应对新冠疫情,我一开始没多想,直到大约十分钟后才意识到,“嘿,等一下。这是一个巨大的项目。”从那时起,我所有其他项目都被搁置了,我对此毫无遗憾。花了三个半月才达到这个地步,还有很多路要走。最初,数据以一系列路径的形式存储在 XML 文件中。然后,在两周后制作了第一个新冠洗手视频之后,我转而使用当前正在使用的时间线和时间帧。那时,许多当前的功能已经包含在内,但持续失败或导致崩溃-烧毁的情况。渐渐地,随着我开发了更多的视频项目,新的功能出现了,而 bug 则缓慢地迁移到代码等同于蟑螂旅馆的地方。时间戳尚未被使用,尽管它们正在被记录,但结果比现在系统性地更卡顿。改进很缓慢,因为我创建了更多的视频,发现自己对正在处理的任何视频项目都如此痴迷,以至于我忍受着我最初启动视频项目是为了帮助我发现和修复的 bug。那时,我在完成整个视频之后才开始纠正我发现的 bug。进度确实发生了,但很缓慢。当我制作 Rose-Bursts 视频时,我改变了这种习惯,并致力于改进屏幕捕捉方法并解决出现的每一个 bug。许多对我来说“足够好”的界面问题不符合这个开源出版的要求,所以在过去一周左右的时间里,很多问题都被发现并修复了。

我在开发精灵编辑器时,开发了该应用程序中使用的许多技术。自从开发动画编辑器以来,`classSprite` 中需要实现一些功能,所以我花时间改进了该项目,并在过去一周左右上传了这些更改。`classSprite` 最重要的更改之一,绝对需要在这里提及,是该类的 `draw_Animation_Frame()`,上面已就小精灵绘制序列进行了说明。

//
 public Bitmap draw_Animation_Frame(ref classSpriteData cSpriteData)
        {
            List<classSprite_Limb> lstLimbsSource = new List<classSprite_Limb>();
            lstLimbsSource.Add(cCostumeInfo_Default.cLimb_Master);
            List<Bitmap> lstBmp = draw_Animation_Frame(ref cSpriteData, lstLimbsSource);
            if (lstBmp.Count > 0)
                return lstBmp[0];
            else return null;
        }

public List<Bitmap> draw_Animation_Frame(ref classSpriteData cSpriteData, 
                                             List<classSprite_Limb> lstLimbSources)
{
...
}
//

这个函数现在有了重载。如上所示,该类现在绘制位图列表,而不仅仅是一个。你可以给该类一个肢体列表,它将生成与原始肢体大小相同的肢体图像。这样,你可以将精灵的胳膊或腿从其主肢体上拆开,并使用“小精灵绘制序列”以你喜欢的任何顺序绘制不同的部分。

一路走来遇到了很多问题,但通过在这个项目和在精灵编辑器中制作/修复功能之间来回切换,让事情变得更容易,因为我的头脑一直都在其中。当然,尽管在有 bug 且未完成的动画编辑器上工作带来了所有麻烦,但我还是很高兴看到我的视频项目成果,这本身就是一种动力。

下一步

  1. 我曾考虑将精灵类与包装器捆绑在一起,并使用演员和视频捕捉来制作一种新型精灵。技术类似于这里使用的技术,只是精灵编辑器会将演员隔离在白墙前,用户需要进行大量编辑才能始终如一地定位演员的质心和关键肢体,以用于创建的任何动画的每一帧。
  2. 关于动画编辑器本身,我计划放弃视频背景(同时将其保留为用户选项),并引入卡通世界的背景、中景和前景。通过跟踪小精灵相对于某个通用卡通城世界中心轴(而不是屏幕上的一个点)的位置,我就可以引入相机视角以及一个在无新冠安全环境中平移和缩放整个卡通世界的相机。我脑海中已有关于此的计划,制作动画卡通听起来是一个有趣的项目,所以我可能很快就会着手处理。

不过现在,我只想完成这篇文章,然后把电脑收起来(差不多),休息一两周,这样我就可以用我的GridMethod应用程序(很可能是阿尔布雷希特·杜勒)来制作另一个艺术项目。但我会带着这个项目的更多更新回来,可能是一篇单独的文章,因为这篇已经很长了。在那之前,你何不邀请杰西卡·兔来你家“隔离和放松”呢,罗杰不会介意的。与此同时,我会处理一些事情,而贝蒂·娃娃会把卡通城那些名声不佳的暴民赶走。

历史

  • 2020年7月16日:首次发布
© . All rights reserved.