abox.tools

语言: 简体中文

怎么把 GIF 拆成一帧一帧

把帧取出来,只要一次拖放加一个按钮。真正值得弄明白的,是 GIF 里的一「帧」到底是什么,因为这个格式存下来的东西和你看见的相当不一样——你的第十四帧之所以是一个装着谁的嘴的长方形,就差在这儿。

打开GIF 拆帧 每一帧都单独存成一张 PNG。

以 Markdown 查看

简短的回答

打开 GIF 拆帧,把 GIF 拖进去,每一帧都会变成一张可以下载的 PNG——一张一张下,或者打成一个 ZIP 一起下。设置不用动,你拿到的正是大多数人想要的那个:每一帧都是完整的画面,就是它在动画那一刻的样子。

这一页剩下的部分,讲的是随后最让人意外的三件事:某一帧只是一小块、透明换个地方就变黑,还有时间——帧一旦成了各自独立的文件,它就不存在了。

GIF 的一帧到底是什么

GIF 不是一摞画。它是一张画,后面跟着一串补丁。

第一帧之后的每一帧,只存那块变过的长方形,外加一条规矩,说明画布接下来该怎么处理。屏幕上其余的一切,不过是前面几帧留在那儿的东西。一个人站在不动的墙前说话,每帧的代价就是一块脸那么大的长方形,而不是一整张画;一个既没有运动补偿、也没有有损环节的格式还不至于完全没法用,全靠这个。

所以「把第 14 帧给我」有两个不同、却同样诚实的答案,这个工具两个都给:

它看上去的样子。那一刻的完整画面:第 14 帧画在它之前的一切之上。这是默认,做联系表、缩略图、要发出去的静帧,或者要送进剪辑软件的帧,要的都是这个。

只有这一帧自己存着的像素。补丁本身,按它自己的大小、自己的位置出来,它没带的地方一律留成透明。第 14 帧可能就是 ⁦60 × 40⁩ 像素的一张嘴。这个视图解释了一个 GIF 的字节都花到哪儿去了;你要是在改这段动画、而不是从里面收割图片,要的就是它。

存下来的帧看着像个碎片,并不说明你的文件有毛病。那就是这个文件。

一段动画的十二个编号帧,每一帧都是完整画面,并标着停留时间。
每一帧都是完整画面,而文件里装的并不是这样:这一节讲的正是这个差别。

处置规则,以及为什么有些帧会留下窟窿

每一帧还带着四条指令中的一条,说明在下一帧画上去之前,它那块长方形该怎么办。在「存着什么」这个视图里,工具会把它写在每一帧下面:

留在屏幕上。最常见的一种。补丁待在落下的地方,下一帧盖上去。

之后清掉自己那块。下一帧落下之前,那块长方形先被擦干净。带着移动的透明物体的动画就是这么做的,而这也是 GIF 闪烁的经典原因。

还原它底下原来的东西。画布回到这一帧画上去之前的样子——盖一个章,再撤销。少见,也是自制的 GIF 读取程序最常做错的一条。

要是你打算比较几个工具,有个细节值得知道:规范说「清掉自己那块」应当还原成背景色,但 1990 年代以来的每一个浏览器都改成清成透明,因为那个年代的动画就是这么设想的。这里的工具是有意跟着浏览器走的,好让你拿到的帧就是你看见过的帧。

设置卡片:在看到的那一帧与文件里存着的原始补片之间做选择,另有一个给透明部分垫底的背景色。
看到的那一帧这一档,会把处置规则重放一遍,交给你的是画面。另一档交给你的是文件里真正存着的东西,连窟窿一起。

透明会怎么样

GIF 的透明只有一位。一个像素要么涂了,要么看不见,中间什么都没有——没有柔和的边,也没有半透的影子。背景透明的 GIF 边缘总是硬硬的、还有点毛刺,就是这个道理。

PNG 能把这一点原样、无损地存下来,所以帧出来时透明是完整的,也不会凭空多出什么。要是这些帧接下来去的地方懂透明,那就留着。

要是不懂,就拿一个颜色填上。忽略 alpha 通道的软件通常会把那儿画成黑的,于是在浏览器里好端端的一帧,到了那边就带着黑底——而一块几乎处处透明的存储补丁,到那边就成了一个装着嘴的黑长方形。事先选好颜色就是解法。它会写进 PNG,之后撤不回来,这也是它没被设成默认的唯一理由。

帧带不走的那些时间

PNG 里没有地方记它在屏幕上待了多久。把动画拆成 PNG,时间就没了,而你一想把它拼回去,这件事立刻就要紧起来。

ZIP 里的 frames.txt 就是为此而在。它列出每一帧的延时、位置和大小,所以这段动画可以在 GIF 制作里、或者别的地方重新搭起来。它只花几 KB,而且事后没有任何办法把它推算回来。

关于 GIF 的延时,有两件事人人都会栽进去:

单位是百分之一秒,所以这个格式能有的最细的一档是 0.01 秒。世上没有正好 30 fps 的 GIF:每帧 0.03 秒是 33.3 fps,0.04 秒是 25。

低于 0.02 秒的一律按 0.10 秒播。浏览器从 1990 年代起就这么封着——一条为那个年代的旋转地球仪写下、之后再没删掉的规矩。文件里写着每帧 0.01 秒的 GIF,声称自己是 100 fps,实际按 10 播。这里的工具显示的是真正播出来的延时,两者对不上时,还会把文件里存的值写在旁边,因为正是这个落差,让一个拆开又拼回去的 GIF 可能比原来慢。

帧的编号,以及为什么要补零

帧出来的名字是 name-001.png、name-002.png,从一开始数,并补零补到最后那个数字的宽度。这不是装饰:在任何文件管理器里,在大多数导入序列的软件里,frame9.png 都排在 frame10.png 后面,因为它们排的是文字,不是数。补过零的名字到哪儿都排得对,而每一个能导入图片序列的剪辑软件也都指望它是这样。

用「每两帧留一帧」把长动画抽稀,不会重新编号。第 42 帧还叫第 42 帧,所以这些文件既对得上原片,也对得上那份时间清单。

为什么这件事不需要服务器

读一个 GIF 是两件活:走一遍文件里的那些块,再把包着它像素的 LZW 压缩解开。两件加起来几百行,在仓库里原样写着,而且跑在你自己的机器上——网线拔了这一页照样能用,原因就在这儿。

你的浏览器早就会放 GIF,只是它不肯把零件交出来:<img> 给你一段动画,把它画到画布上永远只给你第一帧,而唯一能多做一点的那个接口,Safari 没有。所以这里干脆自己把这个格式读一遍,在每个浏览器里都是同一套做法——而正因为是自己读的,才谈得上把补丁和处置规则摆给你看。

把文件传给在线转换器安全吗?那一页列了四条检查,它们会告诉你关于任何工具的同一件事,也包括这一个。