将视频转换为小体积 APNG

APNG虽然受很多用户喜爱,但对某个组织来说却不受欢迎,所以到现在也没有一个能够将 APNG 压缩到很小的体识的流行库。

有压迫就有反抗,有开发者专门为APNG优化了压缩算法,经我粗略测试,压缩的体积能够小 20 多倍。

如果直接用ffmpeg转换视频成得到的 apng 文件,体识巨大,是远远超过很多网站的图片上传限制的,所以我们需要的是小体积 apng。

因为简书和思否会无脑压缩图片,压缩时不会识别动图,导致压缩后的 PNG 动图变成了一张静态,所以简书和思否用户请移步博客园查看未经压缩的示例动图,同时也由于简书会将外链图片上床到自己的服务器且有 10 Mb 限制,所以只能将一张高清动图压缩到了640x360分辨率,但图中色彩丰富,每帧变化较多,排除掉分辨率的原因整体图像几乎无损,同样的视频不经apngasm压缩,体积将会从现在的 7.4M 暴增到 20M:

output

1 分解视频

将视频分解为多张图片,方法有很多种,这里提供一个在线分解网站:Video to PNG image sequence converter (ezgif.com)

将分解完成的压缩包下载解压待用。

2 合成为动图

这里用到的软件是shgodoroja/APNGb: macOS app which assembles and disassembles animated png files (github.com),虽然此库数年未更新,但其基于的 APNG 压缩库apngasm/apngasm: The next generation of apngasm, the APNG Assembler. (github.com)不会过时,依然好用。

下载后,打开软件,将第一步分解得到的所有图片扔进去:

截屏2021-06-01 11.53.56

调整主要参数:

  • Loops 循环次数,0 为一直循环
  • Compression 压缩算法,默认即可,有兴趣的可以尝试不同算法压缩
  • All frames delay 每一帧的延迟,说白了就是每一帧的显示时间,或一秒多少帧。上图中为一秒 40 帧。
    • 分解图片数量固定的情况下,帧率高意味着图片加速播放,帧率低,图片减速播放
    • 帧率的高低不影响最终图片的体积大小
  • Selected frame/s delay 选中帧的延迟,解释同上

双击左上角三大金刚键右侧的方块或三角即开始压缩图片,过程很漫长,请耐心等待。

3 示例结果

上例中,使用 153 张图片合成的动图,用ffmpeg转换为apng的体积和用上述软件转换的体积对比:

image-20210601121537558

ffmpeg并不会压缩图片,而是将多张图片粗暴地合并为一张动图,因此体积巨大。

由此可见压缩效果是很明显的,而且我目测 2.4 MB 虽然体积小,但没什么损失,图片质量极高。

因为 49.3 MB 体积巨大,没办法上传到文章中,所以我将两副图片上传到网盘中,有兴趣的可以下载下来对比:https://zijieyunpan.com/UNw5G5iMX4J

4 所有系统可用

可能不是所有系统都有可用的软件,但 APNG 压缩库apngasm/apngasm: The next generation of apngasm, the APNG Assembler. (github.com)却适用于所有平台。

Mac 版软件上面的示例中已提供下载链接。

Windows 版:APNG Assembler (sourceforge.net)

Linux 版没有找到,但可以自行编绎 APNG 压缩库并安装,安装好后直接调用apngasm命令即可压缩多张图片:

apngasm -o output.png 图片1.png 图片2.png 图片3.png 图片4.png 图片5.png ...

如果多张 png 文件名有规律且放到同一个文件夹内,此文件夹内有且只有这些图片,则可以直接输入下面的命令:

apngasm -o output.png 文件夹路径/*

Linux 安装可能遇到的问题

因为libapngasm.so库默认安装在/usr/local/lib中,导致在调用apngasm命令时报错error while loading shared libraries: libapngasm.so,此时需要将此文件软链接到/usr/lib中即可:

sudo ln -s /usr/local/lib/libapngasm.so /usr/lib/libapngasm.so

4.1 直接使用apngasm

写了一个简单的脚本:

#!/bin/bash
# convert_to_apng.sh
set -e

input=${1}  # 源视频文件
pngs_folder=${2}  # 分解的图片存储目录
format=${3}  # 图片的文件名格式
fps=${4}  # 以多少帧率分解视频,如果是 10 则以每秒 10 帧的帧率分解视频 
output=${5}  # 生成的 png 动图名,不含 .png 后缀,只传入文件名
delay=${6:-100} # 每帧显示的时长,默认 100 ms,在调整 fps 后需要手动调整 delay 来对动图加速或减速播放
scale=${7:-""}  # 压缩分辨率,在源视频分辨率太高时使用

# 分解视频为图片
if [ ! -d ${pngs_folder} ];then
    mkdir ${pngs_folder}
else
    rm -f pngs/*
fi
echo "正在分解视频"
if [ ${scale} ]; then
    echo "先压缩分辨率,再分解视频"
    ffmpeg -i ${input} -vf "fps=${fps},scale=${scale}" ${pngs_folder}/${format}.png
else
    ffmpeg -i ${input} -vf fps=${fps} ${pngs_folder}/${format}.png
fi
echo -e "视频已解压完成,所有图片保在 ${pngs_folder} 目录中"

echo "开始压缩图片"
apngasm -o ${output}.png ${pngs_folder}/* -F -d ${delay}  # -F 参数会覆盖与 output 同名的文件
echo "apng 已制作完成"

将源视频文件input.mov分解为图片,这些图片保存到pngs目录中,图片文件名的格式是%03d,每秒 5 帧将图片分解为多张图片,最后的动图文件名为output.png,动图每帧显示时长100ms,视频等比例压缩为高为360的视频:

./convert_to_apng.sh input.mov pngs %03d 5 output 100 -2:360
  • 文件名格式:%04d是四位自增的数字,不足四位时向前补0

    • 0001.png0022.png0111.png1234.png
    • 分解得到的图片一般不可能超过 3 位数,不然动图体积可能超过 1 G,完全没有必要,所以格式推荐使用%03d
    • 除自增数字外,其前后还可以加一些自定义字符串,如test_%03d
  • 压缩分辨率:参考ffmpegscale参数

    • 建议保持比例缩放
    • 上例中指定高为 360 的等比例缩放,你也可以指定宽为 720 进行等比例缩放720:-2
    • 但不能宽和高都使用 -2
    • 你也可以同时指定宽和高720:480,这样的话压缩后的视频将不是等比例
  • delay:一般不用修改此参数,除非你对fps进行了非常夸张的修改,导致分解的图片非常少或非常多才需要调整。

    • 图片数量非常少时,需要调大此参数,延长每张图片的显示时长
    • 图片数量非常多时,需要调小此参数,缩短每张图片的显示时长
    • fps[5, 10]范围内不需要设置delay,使用默认的 100ms 即可

delayscale都是可选参数,正常情况下一般不用这两个参数:

./convert_to_apng.sh input.mov pngs %03d 5 output

这两个参数虽然可选,但因为都是位置参数,所以在传入scale时必须先传入delay(可传入默认值 100),传入delay时可不传入scale


结束,希望各位读者能愉快使用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容

  • 表情是什么,我认为表情就是表现出来的情绪。表情可以传达很多信息。高兴了当然就笑了,难过就哭了。两者是相互影响密不可...
    Persistenc_6aea阅读 124,504评论 2 7
  • 16宿命:用概率思维提高你的胜算 以前的我是风险厌恶者,不喜欢去冒险,但是人生放弃了冒险,也就放弃了无数的可能。 ...
    yichen大刀阅读 6,041评论 0 4