上文中,我们利用convert命令制作了gif格式的文件。实际运用中,视频格式的动图因为可以随时进行暂停、前进、后退等操作,在讲解时,更容易让听众理解。本文中,我们基于前文绘制的多日的海表温度图,利用ffmpeg和python两种不同方法,将前文所绘GIF动图转化为视频(MP4格式)。
同样,我们先上结果。
知乎视频www.zhihu.com- 利用FFMPEG工具将GIF格式转化为MP4
首先,我们直接利用ffmpeg命令,将之前生成的gif文件直接转化为视频文件。命令如下:
4 -f gif -i sst.gif -vf
注:ffmpeg需要利用Macport/Homebrew等工具安装。
各个选项的解释如下:
-r: 帧数。 -r 4 即为每秒4帧。
-f:强制输入[输出]格式。 我这里只写了输入格式。
-i: 输入文件
-vf: 我个人的理解是针对视频进行滤波设置。其后跟着的则是具体设定。scale=iw:ih,format=yuv420p表示视频的宽为iw(输入文件的宽),高为ih(输入文件的高),视频存储格式为于yuv420p。这里视频的宽高也可以直接指定数字,或者是对iw/ih进行缩放,如1920:1080或iw/2:ih/2。
利用ffmpeg时,我们需要先利用convert生成gif文件,然后才能生成视频文件。而convert命令在对于大量图片操作时,就比较吃力了。我之前想用400多张2Mb大小的图制作gif,我的笔记本跑了一下午都没结束。通过观察convert命令的行为和资源占用,我发现convert命令需要将全部图片读入内存,才能进行转换,因此我在处理大量文件时并不推荐使用convert制作动画。
- 利用FFMPEG工具直接制作MP4
4 -pattern_type glob -i
这条命令可以直接将图片转为MP4格式。这里需要提到一点,直接利用ffmpeg制作动画时,有时会遇到报错: width not divisible by 2 。这时候需要一点小技巧,如下:
4 -pattern_type glob -i
由于分辨率并非2的倍数,因此我们利用之前提到的scale参数对原始的长宽进行调整,分别除以2,进行截断后(trunc函数)再乘以2,得到一个2的倍数。
- 利用Python的opencv模块制作MP4
我这里再介绍一下如何用Python来制作动画。Python的制作原理其实与ffmpeg直接制作动画类似,都是依次读取图片然后制作mp4。
依照惯例,先上代码。
import
这段代码非常简单,我来简单说明以下。
首先,我们需要利用的模块有opencv,os和datetime三个,其中制作动画主要利用opencv。datetime是为了进行日期循环,os则是对应文件操作。
为了制作原始分辨率的动画,我们利用cv2.imread直接读取了图片中的一张,然后通过img.shape得到图片的长宽,类似于之前的scale的iw和ih。
输出则是用 cv2.VideoWriter来控制,四个参数分别为输出地址,格式,每秒帧数和分辨率。
注:这里有个问题,如果用fourcc的结果带入,会出现OpenCV: FFMPEG: fallback to use tag 0x7634706d/'mp4v'之类的错误,因此我直接将0x7634706d写在格式一栏。
之后,便可以根据循环来读取每帧所用到的图片了:cv2.imread(im_name)。然后利用 videoWriter.write写入视频。
最后,用videoWriter.release()来结束视频操作。
- 小结
本文中,我们介绍了两种制作动图转动画的方法(python不算转化,而是直接制作动画)。两者其实各有优缺点,总结如下:
ffmpeg
- 优点:命令简单易懂;可配合convert可以对矢量图进行操作(类似栅格化);可以直接在gmt的bash script尾端添加中,一次性解决
- 缺点:convert命令难以操作大量文件;单独ffmpeg是可以快速操作大量文件的
opencv
- 优点:可以对大量文件进行转换
- 缺点:需要会python,代码相对较长(不如ffmpeg一条命令直接转换来的方便)
总体来说,以上的两种方法需要各位针对个人的不同需求,分别选择。除了这两种方法以外,也许还有其他更好的方法,欢迎各位留言指教,谢谢。