APNG受到很多用户的欢迎,但不受某个组织的欢迎,所以直到现在还没有流行的库可以将APNG压缩成小尺寸。哪里有压迫,哪里就有反抗。一些开发者专门针对APNG优化了压缩算法。经过我粗略的测试,压缩后的体积可以小20多倍。如果直接使用ffmpeg将视频转成得到的apng文件,体积巨大,远远超过很多网站的图片上传限制,所以我们需要的是一个小尺寸的apng。因为简书和四物会不假思索地压缩图片,压缩的时候不会识别动画,导致压缩后的PNG动画变成静态图片,所以简书和四物的用户请到博客园查看未压缩的同时,因为简书会将外链图片上传到自己的服务器,有10Mb的限制,所以只能将一张高清动画压缩到640x360分辨率,但是图片中的颜色很丰富,有很多变化每一帧,排除分辨率后整体图像几乎无损。同一个视频不经过apngasm压缩,体积会从现在的7.4M增加到20M:1Decomposethevideo将视频分解成多张图片,方法有很多种,这里有一个在线分解网站:VideotoPNG图像序列转换器(ezgif.com)。下载解压解压后的压缩包,以备后用。2这里使用的软件是shgodoroja/APNGb:macOSappwhichassemblesanddisassemblesanimatedpngfiles(github.com)。虽然这个库几年没更新了,但是它是基于APNG压缩库apngasm/apngasm:下一代apngasm,APNGAssembler。(github.com)不会过时,但仍然有用。下载后打开软件,将第一步分解得到的图片全部丢进去:调整主要参数:循环次数,0是一直循环的压缩算法,默认就好,那些有兴趣可以尝试不同的算法来压缩Allframesdelayevery一帧的延迟,说白了就是每一帧的显示时间,或者每秒多少帧。在上图中,它是每秒40帧。当分解图片的张数一定时,高帧率代表图片加速播放,低帧率代表图片减速播放。帧速率不会影响最终图片的大小。三个菱形键右边的正方形或三角形会开始压缩图片,过程很长,请耐心等待。3示例结果上面的例子,使用153张图片合成动画,ffmpeg转成apng的体积和上面软件转换的体积对比:ffmpeg不对图片进行压缩,只是粗略的将多张图片合并成一张动态图,所以体积很大。可以看出压缩效果非常明显,我目测2.4MB虽然体积小,但是没有损失,画质极高。因为49.3MB体积巨大,没办法上传到文章中,所以上传了两张图片到网盘。有兴趣的可以下载对比一下:https://zijieyunpan.com/UNw5G...4所有系统都可以用软件不是所有系统都可以用的,但是APNG压缩库apngasm/apngasm:下一代apngasm,APNG汇编程序。(github.com)适用于所有平台。上例中提供了软件Mac版本的下载链接。对于Windows:APNG汇编程序(sourceforge.net)。linux版本没找到,不过可以自己编译安装APNG压缩库。安装后可以直接调用apngasm命令压缩多张图片:apngasm-ooutput.png图片1.png图片2.png图片3.png图片4.png图片5.png...如果多个png文件有正则名字和都放在同一个文件夹下,而这个文件夹里只有这些图片,可以直接输入以下命令:apngasm-ooutput.png文件夹路径/*linux安装可能会遇到问题,因为安装了libapngasm.so库默认在/usr/local/lib中,导致调用apngasm命令时加载共享库时报错error:libapngasm.so。这时候需要安装这个软链接文件到/usr/lib:sudoln-s/usr/local/lib/libapngasm.so/usr/lib/libapngasm.so4.1直接用apngasm库写一个简单的脚本:#!/bin/bash#convert_to_apng.shset-einput=${1}#源视频文件pngs_folder=${2}#分解图片存储目录格式=${3}#图片文件名格式fps=${4}#以多少帧率分解视频,如果为10,则以每秒10帧的帧率分解视频output=${5}#生成的png动画的名称,不带.png后缀,只有文件名delay=${6:-100}#每帧显示时长,默认100ms。调整fps后,需要手动调整延迟来加速或减速动画。scale=${7:-""}#压缩分辨率,在源视频分辨率过高时,使用#将视频分解成图片if[!-d${pngs_folder}];然后mkdir${pngs_folder}elserm-fpngs/*fiecho"分解视频"if[${scale}];thenecho"先压缩分辨率,再分解视频"ffmpeg-i${input}-vf"fps=${fps},scale=${scale}"${pngs_folder}/${format}.pngelseffmpeg-i${input}-vffps=${fps}${pngs_folder}/${format}.pngfiecho-e"视频已经解压,所有图片都保存在${pngs_folder}directory"echo"开始压缩图片"apngasm-o${output}.png${pngs_folder}/*-F-d${delay}#-F参数会覆盖与输出同名的文件echo"apnghasbeenmade”,将源视频文件input.mov分解成图片,这些图片保存在pngs目录下。图片文件名格式为%03d,每5帧保存一张图片。最终的动画文件名为output.png,每帧动画显示时间为100ms,视频等比例压缩为360的视频:./convert_to_apng.shinput.movpngs%03d5output100-2:360文件名格式:%04d为四位数字自增数,少于四位比如0001.png,0022.png,0111.png,1234.png超过3位不能分解。否则动画的体积可能会超过1G,完全没有必要,所以推荐格式除了自增数,可以在使用%03d前后添加一些自定义的字符串,比如test_%03d压缩resolution:参考ffmpeg的scale参数,建议保持比例缩放。在上面的例子中,指定高度等于360,你也可以指定宽度720,比例缩放720:-2,但你不能同时使用-2作为宽度和高度。也可以同时指定720:480的宽高,这样压缩后的视频就不会按比例延迟了:一般这个参数不用修改,除非你对fps做了很夸张的修改,导致极少或大量的分解图片需要调整当图片数量很少时,需要增加这个参数来延长每张图片的显示时间。当图片数量很大时,需要减小该参数以缩短每张图片的显示时间。fps在$[5,10]$延迟范围内不需要设置,使用默认100ms。delay和scale都是可选参数。./convert_to_apng.shinput.movpngs%03d5output./convert_to_apng.shinput.movpngs%03d5output这两个参数是可选的,但是因为都是位置参数,所以在传入scale的时候,必须先传入delay(可以传入默认值100),传入delay时不能传入scale,到此结束,希望各位读者使用愉快。
