Ser*_*rge 9 compression performance image gif animated-gif
我们正在建立一个在线视频编辑服务.其中一项功能允许用户将视频中的短段导出为动画gif.Imgur 每个上传的动画gif 的文件大小限制为2Mb.
Gif文件大小取决于帧数,颜色深度和图像内容本身:坚固的平面颜色导致非常轻量级的gif,而一些随机颜色电视噪声动画将非常沉重.
首先,我将每个视频帧导出为最终GIF帧大小的PNG(固定,384x216).
然后,为了最大化gif质量,我进行了几次gif渲染尝试,参数略有不同 - 不同的帧数和gif调色板中的颜色数.在保持文件大小限制的情况下具有最佳质量的渲染会上传到Imgur.
每个渲染需要时间和CPU资源 - 我希望优化.
问题:根据实际图像估算最佳渲染设置的最佳方法是什么,尽可能接近文件大小限制,并至少将渲染尝试次数降至2-3?
GIF图像格式使用LZW压缩.臭名昭着的算法专利Unisys的所有者,正如图像格式受欢迎一样积极地追求版税支付.结果很好,我们得到PNG感谢.
LZW可以压缩图像的量非常不确定,并且很大程度上取决于图像内容.您最多可以为用户提供估计最终图像文件大小的启发式方法.例如,使用彩色条显示成功预测.只需转换第一帧,您就可以很快地为它着色.这不会花费很长时间在384x216图像上,这个图像在人类时间运行,只需几分之一秒.
然后将第一个图像的有效压缩率外推到后续帧.哪个应该只编码与原始帧的小差异,因此应该具有可比较的压缩率.
在编码整个序列之前,您无法真正知道它是否超出了站点的大小限制.所以一定要在你的UI设计中强调你的预测只是一个估计,所以你的用户不会太失望.当然,为他提供了降低尺寸的工具,例如最近邻插值,使图像中的像素更大.专注于使后面的帧变得更小可以获得丰厚的回报,GIF编码器通常不会自己做得很好.因人而异.
没有简单的答案。单帧GIF大小主要取决于量化后的图像熵,您可以尝试使用stddev作为估计器,例如使用ImageMagick:
identify -format "%[fx:standard_deviation]" imagename.png
Run Code Online (Sandbox Code Playgroud)
您可以通过在图像上运行平滑内核来消除一些不太可能产生信息的高频噪声,并且很可能破坏压缩性能,从而获得更好的结果。无论如何,使用JPEG比使用GIF更好。
然后,通常,您需要运行大量样本以得出某种类型的样本(假设您有一个压缩参数Q)
STDDEV SIZE W/Q=1 SIZE W/Q=2 SIZE W/Q=3 ...
value1 v1,1 v1,2 v1,3
Run Code Online (Sandbox Code Playgroud)
在运行了几十个测试(但是您只需要执行一次,而不是“在运行时”)之后,您将获得对的估计和对错误的度量。然后,您会看到具有stddev 0.45的图像在Q = 1时压缩为108 Kb,在Q = 2时压缩为91 Kb负5,而在Q = 3时压缩为88 Kb负3,依此类推。
到那时,您得到一个未知的图像,获取其stddev和压缩@ Q = 1,并且可以在Q等于4时内插可能的大小,而无需实际运行编码。
当您的服务处于活动状态时,您可以存储统计数据(即,在真正进行编码之后,您可以存储实际结果)以进一步改善估算;毕竟,您只会存储一些数字,而不存储视频中可能存在的任何潜在敏感或个人信息。获取和存储这些数字几乎是免费的。
识别背景固定的图像可能是值得的。在这种情况下,您可以进行一些修改以使某些区域中的所有帧相同,并使GIF动画算法不存储该信息。这一点,当和如果你得到这样的视频(例如说话的头部),可能会导致巨大的储蓄(但会抛出完全关闭参数估计的事情,除非你也估计背景区域的实际程度。在这种情况下,假设此区域为B,将帧区域为A,则五帧的压缩“图像”大小将为A +(AB)*(5-1)而不是A * 5,并且您可以将此校正因子应用于估算值)。
然后有一些优化技术,可以对图像进行稍微的修改并使其适应更好的压缩效果,但是我们会偏离当前的主题。我有几种算法与调色板PNG配合得很好,在很多方面都与GIF相似,但是我需要检查是否可以自由使用它们。
一些想法:LZW算法继续在行。因此,每当N个像素序列与已经遇到的序列“(小于或等于X%)”(在感知上或算术上)不同时,请重写该序列:
018298765676523456789876543456787654
987678656755234292837683929836567273
Run Code Online (Sandbox Code Playgroud)
此处第一行中的656765234序列与第二行中的656755234序列几乎匹配。通过将不匹配的5更改为6,LZW算法可能会拾取整个序列,并用一个符号而不是三个(6567、5、5234)或更多符号来存储它。
同样,LZW使用位,而不是字节。这意味着,非常粗略地说,越是在0和1间的平衡时,更糟糕的压缩会。它们的顺序越不确定,结果越差。
因此,如果我们找到一种使分配更加“对称”的方法,我们将获胜。
而且我们可以做到这一点,我们可以做到无损(相同的作品与PNG)。量化图像后,我们选择图像中最常见的颜色。假设该颜色为颜色索引0。即为00000000,八个胖零。现在,我们选择紧随其后的最常见的颜色,或第二最常见的颜色。然后给它索引1,即00000001。另外七个零和一个单一的1。接下来的颜色将被索引为2、4、8、16、32、64和128;这些中的每个仅具有一个比特1,所有其他比特均为零。
由于颜色很可能会根据幂定律进行分配,因此可以合理地假设大约20%的像素将使用前九种最常见的颜色进行绘制;并且可以使20%的数据流至少为87.5%的零。它们中的大多数将是连续的零,这是LZW不会无休止的认识。
最重要的是,这种干预是完全无损的。重新索引的像素仍将是相同的颜色,只有调色板会相应地移动。几年前,我为PNG开发了这样一种编解码器,在我的用例场景(PNG街道地图)中,它产生了很好的结果,压缩率提高了约20%。使用更多不同的调色板和LZW算法,结果可能不会那么好,但是处理速度很快,实现起来也不太困难。