GIF应用程序开发–如何开发GIF编码

发布于:2021-01-30 11:25:20

0

117

0

Android 博客 开发 Java Kotlin

在本文中,我们将简要列出可以帮助您进行GIF文件编码的库,这是GIF maker应用程序开发过程中的一个重要部分。请注意,项目在不断发展,有些项目遭到否决,有些项目出现了新的项目。

为什么GIF编码如此复杂?

似乎用一系列图像制作GIF文件就像制作一个视频文件一样,只是格式不同。好吧,没有什么比这更离谱了!请记住,GIF格式是在1987年开发出来的,30多年前,一开始甚至不支持动画。这就是为什么它有一些限制,使编码有点困难。

调色板

最重要的问题是一个GIF帧最多可以包含256种颜色(包括透明的)。在给定时刻可见的快照可能由多个帧组成。这是因为一个帧的大小可能小于整个画布。另外,帧可以包含透明像素。如果我们想对一个超过256色的帧进行编码,我们必须对它进行某种变换。有几种方法可以解决这个问题,其中一些方法也可以结合使用。

其中之一是抖动。粗略地说,它通过混合更多不同的颜色来模拟中间颜色。你可以在下图中看到一个例子。请注意,图像仅由完全黑色和完全白色的像素组成。然而,抖动引入了灰度错觉。

如果所有的帧都可以存储(无论是在内存中还是以视频文件的格式),我们可以首先检查所有帧,检查使用的颜色和频率(创建直方图),并建立一个最佳的调色板。有几种方法可以创建这样的直方图。例如,FFmpeg的palettegen过滤器支持3种不同的统计模式。

每个GIF帧可以有自己的调色板(如果没有,则使用全局调色板)。使用单独的调色板,我们可以在整个文件中有更多的颜色。但是,多个选项板会消耗额外的存储空间和解码时间。根据动画长度、画布大小和用法,它可能有意义,也可能没有意义。您可以在有关高质量GIF编码的文章中了解更多信息。

请注意,GIF格式只支持透明性(alpha位-像素可以是完全透明的或完全不透明的),而不支持半透明性(alpha通道-细粒度透明级别)。这意味着,如果源包含半透明像素,则它们在输出GIF文件中会显示为透明或不透明。请看以下图片:

GIF文件编码示例GIF文件编码示例

时间表

每个帧可以有自己的延迟。显示帧的时间。延迟的测量单位为厘米秒(1个单位=0.01秒)。每秒100帧听起来不错。然而,由于GIF解码通常比视频(通常是硬件加速)慢,因此引入了限制。最低值(最短延迟)被人为地增加到更高的值。更重要的是,增加后的值通常不是最小值,而是更高的值!

例如,在撰写本文的环境中,有效的最小延迟为0.02s。所有较小的延迟都增加到0.01s。请参见下面的动画:

                                                                              

延迟0.01s的GIF(可以像0.1s一样可见)

另请参阅动画GIF最小帧延迟浏览器兼容性研究(这也是上述图片的来源),以了解不同浏览器中的更多示例。您可能对web存档副本感兴趣,因为原始网站上的图像已死亡。选择最小值不是一件容易的事。

安卓

运行Android的设备(主要是智能手机和平板电脑)通常比同时使用的PC具有更少的高性能硬件,因此优化在这里具有重要意义。这意味着Android应用程序中的GIF编码通常是本地完成的(使用C / C ++和JNI,不要与本地–非混合,非Flutter应用程序混淆)。

幸运的是,当您在应用程序中开发GIF编码时,并不总是需要进行如此低级的抽象。最流行的图像/视频编码库之一是FFmpeg。Android开发者友好版还没有正式提供。但是,确实存在一些包装器。在编写时,最流行的是移动FFmpeg。当您只想从某个输入源生成GIF时,这样的东西可能就是您所需要的全部。

如果您想操作一些更特定于GIF的属性,如单个帧上的处理方法或修改GIF文件元数据,您可能会对gifsicle感兴趣。不幸的是,它既没有官方的Android绑定,也没有著名的非官方端口。您需要从源代码处编译它。

总结

GIF编码不是一个简单的过程。由于GIF不是为现代动画设计的,我们需要借助非常复杂的技术来获得令人满意的效果。幸运的是,我们不需要从头开始写。这个主题非常流行,所以有现成的库,至少可以用于应用程序的低级部分。