记录webp动图层叠(残影)问题

2,252 阅读3分钟

起因

起因大概是想做个动图玩玩,但是gif的渣画质和体积并不能使人满意,于是便想到了webp这个小可爱。 webp的动图据说可以支持更多的色彩以及它的压缩率也更优秀,听起来很美,但实际怎么样呢?

过程

找朋友把一段模型小人动画导出了视频,再尝试用ffmpeg转成webp动图,命令如下

./ffmpeg -i 30.mov -vcodec libwebp -filter:v fps=fps=30 -lossless 0 -compression_level 6 -q:v 75 -loop 1 -preset picture -s 514:563 output.webp

主要选项:

  • 将每秒帧率设为30: -filter:v fps=fps=30
  • 设为导出为无损质量: -lossless 0 ( 0为有损,1为无损 )
  • 设为循环播放: -loop 0。 设为不循环播放: -loop 1
  • 设置预设渲染模式 -preset default , 可按视频画面内容类型设置 picture, photo, text, icon, drawing 或 none。选择合适的渲染模式可导出更小的 webp 文件。
  • 将导出 webp 文件分辨率设为 514px*563px: -s 514:563

最终得到的结果 点击查看

what ??? 为什么会这样,陷入迷茫中。。。

解决

在网上搜索了一堆之后,也发现了几个人出现的类似情况(但是确实太少了。。),尝试了他们说的解法也并未生效。。。

这个现象会出现在背景为透明的时候,不透明的时候看起来还正常,一旦透明立刻就开始残影,谷歌官方的libwebp工具里有一个webpmux,可以用来生成webp动图,于是我们来查看一下谷歌的 文档说明

image.png

大致意思如下:

file_i 是帧图片 (WebP 格式) ,xi,yi 为此帧指定图像偏移量,di 为下一帧之前的暂停持续时间,mi 为此帧的 dispose 方法(0为 NONE,1为 BACKGROUND) ,bi 为此帧的混合方法(+ b 为 BLEND,-b 为 NO _ BLEND)。参数 bi 可以省略,默认为 + b (BLEND)。另外,如果省略 bi,则 mi 可以被省略,并且默认为0(NONE)。最后,如果 mi 和 bi 被省略,那么 xi 和 yi 可以被省略,并且默认为 + 0 + 0。

听起来蒙蒙的。。。重点就在mi这个参数上,mi为此帧的dispose方法,默认为0(0为 NONE,1为 BACKGROUND),设置为0时,每一帧不会清除上一帧的画面。

换句话说设置为1,就正常了!!!

可惜然并卵,尝试将webp拆成一张张帧图,再通过webpmux合并,结果还是会出现残影,难道这年头谷歌出品的工具都不好使了?

原来错的不是我,而是这个世界!(x)

最后发现是WPS图片是大锅,不管是不是有残影,都会显示残影,而且还有其他显示问题,没想到虽然支持webp,但是webp动图显然支持的不好,误导了我这么久,呜呜呜,我要卸载了你(x)

这下我们扔到chrome浏览器去查看,我就不信这都不行!

果然,成功了!如果你使用的也是chrome或chrome内核的浏览器,请 点击查看

这里再提一个更简单的方法,可以修复层叠的webp动图,也是一位掘金老哥的帖子 方便修改webp动画参数, 修复ffmpeg转出webp层叠展示的小工具 - 掘金 (juejin.cn)