写博客时常常需要将 MP4 视频转换成 gif,方便插入。网上有挺多网站可以在线转,但是质量一般,有的还有文件大小或数量限制,其中,在 Linux 命令行下,很容易就能实现这个功能。
工具选择:
- 截取视频中的图片:mplayer
- 合并处理 gif:imagemagick
安装命令
sudo apt-get install mplayer
sudo apt-get install imagemagick
完成转换需要完成三项工作:将视频转换为 jpeg,将 jpeg 合成 gif,压缩 gif 文件
0x00 利用 mplayer 将视频转换为图片
假设 MP4 文件在 ~/Video/ 目录下,文件名为 screenrecorder.mp4
cd ~/Video
mplayer -ao null screenrecorder.mp4 -vo jpeg:outdir=.tmp
-ao null 表示不输出音频
-vo jpeg 表示将视频输出为 jpeg
:outdir=.tmp 表示将 jpeg 输出到当前目录下的 .tmp 文件夹中
0x01 将图片合成 GIF
接下来需要用 imagemagick 将多张图片合成 gif。
convert .tmp/*.jpge screen.gif
这个操作极为耗时,而且会报下面一个错误:

这个错误之所以出现,是因为 ImageMagick 在其安全策略配置文件中,将 ImageMagick-6 的内存使用限制为 256MB,导致 ImageMagick 不能获得足够的内存来完成图片合成。
ImageMagick 的安全策略配置文件位置可以通过 identify -list policy
获取,一般为 /etc/ImageMagick-6/policy.xml。然后用你喜欢的编辑器打开文件找到下面一行进行编辑即可,注意,编辑此文件需要管理员权限。
<policy domain="resource" name="memory" value="6144MiB"/>
具体改成多少可以看你机器的配置而定。
0x02 压缩生成的 GIF 文件
直接合成的 gif 图片尺寸过大,以我 28 秒录屏为例,生成 865 张图片,合成的 gif 体积高达 109.1MB,如果直接使用,简直是不可想象的,因此还需要使用 ImageMagick 进一步压缩。
# 原尺寸
ls -l screen.gif
# -rw-rw-r-- 1 zeamonk zeamonk 109146833 10月 4 22:48 screen.gif
# 压缩
convert screen.gif -fuzz 15% -layers Optimize 1.gif
# 压缩后尺寸
ls -l 1.gif
# -rw-rw-r-- 1 zeamonk zeamonk 1.7M 10月 5 01:19 1.gif
-fuzz 选项启用后会将相近的颜色会被压缩为同一种颜色,后面的值表示颜色相近区域的范围,数越大代表范围越大,图片失真越严重。实测 15% 的情况下失真是可以接收的,如果将 -fuzz 设为 20%,文件尺寸可以进一步压缩到 900k,但失真会比较严重。
下图是 15% 压缩的图片

详细讲解可以看压缩gif的正确姿势
0x03 偷懒写脚本
为了方便使用,还是写个脚本吧。
# 生成 jpg 文件
echo "Generate pictures..."
out1=`mplayer -ao null $1 -vo jpeg:outdir=.tmp > /dev/null`
# 预处理,对文件进行压缩
echo "Compress picture..."
out2=`find .tmp/*.jpg -exec convert {} -strip -resize 75% -quality 75% {} \;`
# 合成 gif
echo "Start converting jpgs to gif..."
out3=`convert .tmp/*.jpg -delay 20 .tmp/tmp.gif`
# 压缩 gif
echo "Optimize gif..."
out4=`convert .tmp/tmp.gif -fuzz 15% -layers Optimize output.gif`
# 清理残余文件
echo "Clear tmp files..."
rm .tmp/* > /dev/null 2>&1
echo "Completed..."
关注下公众号好不好😘😘😘

网友评论