来源:优设 作者:阿杰
腾讯某位同学设计的动态表情上线后,发现锯齿问题特别严重,向工程师请教,前端小哥拿出自家研究的神器,立刻解决了问题,而且还可以批量搞定哟,已经有大量好评了,现在知道还来得及。
前端:GIF本来就会有锯齿,跟我没关系呀。
设计师:太丑了,你不是万能的前端么?这个问题我用ps解决都是分分钟的事情呀!
前端: ……(you can you up) 其实,在很久很久以前…
2004年,mozilla社区也意识到这个问题,所以当时他们提出了一种新的图片格式——APNG。
APNG又叫动态PNG(Animated PNG),第1帧为标准PNG图像,剩余的动画和帧速等数据放在PNG扩展数据块里,因此只支持原版PNG的软件会正确显示第1帧。更多资料请查看:wikipedia.org
由于APNG是PNG的扩展,所以它支持半透明,自然就不会有锯齿的问题。设计师:能说人话么?
前端:- -!APNG比GIF牛逼多了,妈妈再也不用担心锯齿的问题了。
设计师:那就赶紧用起呀!
这时产品出现了…
产品: 不会有锯齿,那是不是APNG会比GIF的体积大呀!
前端:just try it…拿一组图片进行测试,会发现有些APNG比GIF要大,如下图:
再通过大批量的图片对比可以发现,APNG平均会比GIF的体积大一点点(3%左右)。更多请查看:
产品:只是大一点点而已,那也很不错了呀!
前端:却多嘛得,如果APNG可以比GIF还要小,这样用户体验不就更好了。先看看APNG的原理:
前方烧脑,做好准备。
APNG对于动态图片的处理算法类似GIF,可以将一组大小相同的PNG图片合并为一张APNG图片,原来的每一张PNG图片变成APNG图片的每一帧,并且每一帧会按照约定的规则来记录与前一帧变化区域的数据到相应数据块,并保存变化区域在图片中的坐标与大小(如图一所示)。解析的时候,应用程序会根据每一帧变化区域的坐标和大小,将变化区域替换前一帧的相应区域来还原当前帧,从而生成动态图片,并达到压缩效果。说起来有点绕口,直接看下面的图会更清晰些:
由于邻近帧间共用了相同的像素信息,所以可以有效节省动态图片的体积。
而由于我们生成APNG的图片是PNG24(为了保证Alpha通道),而PNG24与GIF相比,体积上本来就没有优势,所以生成的APNG自然也没有优势。
不就是PNG24比较大嘛,那就将PNG24先有损压缩(pngquant),再转换为APNG不就可以了,喜大普奔呀!^_^最后按这种方式折腾出来了,却发现APNG比之前更大了(如下图)!- -,知道真相的我眼泪掉下来呀!请查看:的对比。
仔细想了一下,因为我们对PNG24进行了有损压缩,造成图片信息的重新排布,本来跟临近帧相同的区域不同了,自然输出的图片大小也会比较大。
所以我们只能对跟临近帧不同的区域进行压缩,具体过程见下图:
按照这种方式优化以后,生成的APNG的大小平均会比GIF小30%左右,而且也能解决锯齿问题(如下图):
点击并在chrome下打开可以有更直观的感受。
设计:虽然不知道你在说什么,但是感觉很厉害的样子!
前端:其实简单来说,就是APNG比GIF小30%左右,而且没有锯齿。
设计:那现在我们可以使用么?会有什么限制么?
前端:额,APNG的平台兼容性不是特别好,不过也是有办法解决的。APNG的经历还是蛮忐忑的,而且最后还是没有形成标准,所以很少应用程序(对于浏览器,目前有firefox与opera支持,还有IOS8下的Safari)支持这种格式,但是不支持的应用程序会显示APNG的第一帧。
对于原生应用,我们可以根据官方说明文档(https://developer.mozilla.org)编写解码逻辑,目前PC QQ客户端已经支持APNG。
对于HTML5应用,已经有比较成熟的开源框架apng-canvas(https://github.com)可供使用,我们在近期的『礼物』项目中就使用了APNG,做到了精细的动画体验(如下图):
产品:那怎么生成APNG呢?如果有大批量的图片需要转换怎么办?
前端:这个不用担心,由于业内暂时没有APNG批量有损压缩的工具,所以我们就自研了iSparta图片转换工具,它有以下特性——
1,批量处理
根据规则对文件和文件夹进行批量转换。具体操作请查看(isparta.github.io)。
2,APNG有损压缩
直接集成PNG的有损压缩,可以将文件体积降低到最小(一般输出的文件比GIF小30%左右)。
3,跨平台
支持windows和Mac系统。
可以点击 下载体验, 目前该工具也在github(https://github.com)上开源了,关于工具的建议与bug可以在issues(https://github.com)上反馈,,也欢迎大家的加入。
任何事情都不是一成不变的,有时候只要跳出常规,再认真一点点,这个世界其实可以更美好。