Welcome to Jiawei Network Technology!

如何压缩SVGA格式的礼物特效文件

2020-12-09 12:07:04

前阵子看到一些使用canvas或者jQuery插件库完成的动画,例如:

http://www.jq22.com/yanshi17061

也可以实现非常棒的效果,还具备一些小的互动。但大多时候,出于工作配合以及对效果的把控,动效/特效还是需要由设计师

自己来完成。而出现在app中的礼物特效最常用的就是使用SVGA格式进行输出。



首先说一下SVGAJSON文件的区别,作为两者的导出工具,BodymovinSVGAConverter是AE对接app过程中最常用的两个插件:


Bodymovin:用于导出JSON文件,如果由矢量作图,且动画效果局限于缩放、位移、旋转以及路径的相关变化这些基础的操作,那JSON完全可以胜任。优点是,占用存储非常小,可以适配不同分辨率且不失真(使用形状图层的前提下)。但是缺点也很明显,无法导出复杂的动画效果,例如AE自带的“Effects & Presets”和常用到的saber、particular、Optical Flares等容易出效果的插件。


SVGAConverter:顾名思义,就是SVGA转换插件。先说一个缺点:AE自带的复杂效果也是无法直接导出的,甚至JSON文件能应用的图层渐变,放在SVGA里也是不适用的,如下图

优点:就是对上述缺点有相应的解决办法。第一,渐变无法导出,可以直接使用图片,导出时会封装在SVGA文件内,相比JSON使用位图素材时会附带产生“img”文件会方便很多;第二,更加复杂的效果(如粒子,光效等),可以通过导出png序列帧再使用插件进行二次导出即可。这个优点也就决定了在做复杂的礼物特效时候大多使用SVGA。其他缺点:当礼物特效过于复杂且时长较长时,文件量会比较大,且占用较大的运行内存。


至于如何导出SVGA,已经有人总结的很好了,这里就不再赘述了,贴地址在下面:

https://www.ui.cn/detail/460267.html





以下内容即针对SVGA第二个缺点进行优化(仅仅是优化,毕竟是使用环境造成了这个缺点),即如何减小SVGA文件大小。



首先区别下面三种SVGA的动画形式:


动画形式A

使用“图片+基础变化”,动画形式简单,可以直接导出SVGA。如下图(网上图片,侵删):

因为本质上是按照“固定图片+图片变化数据”的方法导出,占用存储空间或运行内存都比较小,所以优化空间比较小。

这里顺便提一下SVGA相较于gif图的优势:

1.颜色更多,gif图只有256种(即只支持8位颜色);

2.体积小,相比于SVGA,gif图是“图片+图片+图片···”的每一帧一张图片的傻瓜模式。


动画形式B

完全是由“帧动画”组成,每一帧都不相同,比较典型的就是C4D制作后导出的动画。如下图所示(网上图片,侵删):

如果要导出此类动画,要先导出PNG序列帧,然后在AE里逐帧排列,再使用插件导出为SVGA文件。如下图:

此类动画压缩仅能采取以下两种方法:


方法一.控制帧率

有些人有时候会忽略帧率的问题而往往使用默认的25FPS或30FPS,然而SVGA的机制便是一帧一帧播放,总帧数=帧率*时长,你可以将它想象成是对GIF图的封装,所以帧率和时长就是影响文件大小的重要因素,在客户对时长进行硬性要求的前提下,就需要控制帧率,事实上14FPS就能满足动效和特效需求。


如下图是将原图的30FPS改成14FPS,也是很流畅的。

方法二.约束长宽范围

如果不是全屏礼物,就确定礼物的有效宽高,避免空间浪费,节省下来的空间就是减小的文件大小。如下图红色线框款选即为有效宽高:


方法三:降低分辨率

首先要说明的是这个方法是会牺牲一定品质的,所以谨慎使用。一般应用在文件量特别大,程序每天来和你谈心的情况下。当然也不是无下限的使用,不要直接就来个长宽各缩小到一半。例如可以将长宽各降低到原来的2/3,这样图片整体面积就只有原来的4/9,最后交给程序再将SVGA拉伸到原尺寸。


这个方法另一个应用,如果将SVGA放置在服务器进行下发,而不是封装在安装包内,设计过程中对应不同分辨率机型导出对应的SVGA文件,用户使用app时,程序通过识别用户设备分辨率从服务区获取相对应的SVGA文件。这样就能避免只使用同一个SVGA文件而在内存较小的旧机型上占用过多运行内存。



动画形式C

这种形式比较复杂,下面是我的近期作品(主体部分是手绘,非C4D)

如上图所示,这种动画形式有固定图片素材的基础运动(包括一部分帧动画),也有光效、粒子等特效。这时通常的做法是按照“动画形式B”来处理,把整个动画导出为PNG序列,再导出SVGA文件。但是这不是最优解。以下是我使用的方法:


方法四:将动画拆分成“动画形式A”+“动画形式B”

我以上面的“天使”进行说明。

动画时长为5s,先将动画进行拆分:

1.动画形式A:天使人体部分(带翅膀)。这部分都是我在PS内一层一层(把头发,四肢,翅膀等都逐一分层)手绘完成,然后导出PNG格式再导入到AE中,动画只有基础的移动、旋转和缩放。且这部分在整个动画的5s中几乎是一直存在的。

如下图:

右眼和翅膀是帧动画,但大部分是一种形态保持不变。下面以右眼为例说明,翅膀同理:

所以这部分动画在最后导出的SVGA文件中,就是以“图片+基础动画数据”存在的,占用非常小的存储空间。所以这部分在工程文件中保留,不做更改。


2.动画形式B:法阵飘散的粒子头上光环特效。这部分都是使用插件制作的,每一帧都是随机的,没有固定的图片素材。如下图(以法阵和粒子为例):

对于这种情况,我们要用到的方法是:


将“用插件做出的效果”转换为“对应时长的PNG序列”

如上图,法阵时间非常短,而粒子占用面积小且画面简单,所以将这两部分导出PNG序列(不要按5s导出,出现了多久就导出多久),文件大小远远小于将全部动画导为PNG序列。导出后再将PNG序列导入原工程文件,放置在对应的时间段和位置,这样效果就和原先保持一样了。

然后再将修改过的整个动画工程文件导出为SVGA文件,就会发现文件量缩小很多。


下图为法阵最后在工程文件中存在的样式:


当然,由于每个人做动画的方式不一样,有人只用C4D制作,有人像我一样,还未掌握C4D技能,只能用手绘+AE的方式制作,因此最后的动画形式都不尽相同,以上只是我个人在工作中总结出的一些压缩方法,可以根据你的动画方式灵活应用。


最后,如果你有更好的方法,欢迎交流和指正。

Taobao store