我有一个充满视频的文件夹,我想将其转换为GIF动画。ffmpeg / avconv直接将其做为不好的工作,因此,我通过首先将每个帧输出为png,然后使用imagemagick转换回gif,将视频转换为gif。问题在于,就文件大小而言,这将导致较大的gif。为了解决这个问题,我想通过转换为gif时跳过每个图像文件或从gif中删除帧,来从gif中“掉落”第二或第n帧。如何在Ubuntu(13.04)上使用imagemagick或其他命令行实用程序执行此操作?
我有一个充满视频的文件夹,我想将其转换为GIF动画。ffmpeg / avconv直接将其做为不好的工作,因此,我通过首先将每个帧输出为png,然后使用imagemagick转换回gif,将视频转换为gif。问题在于,就文件大小而言,这将导致较大的gif。为了解决这个问题,我想通过转换为gif时跳过每个图像文件或从gif中删除帧,来从gif中“掉落”第二或第n帧。如何在Ubuntu(13.04)上使用imagemagick或其他命令行实用程序执行此操作?
Answers:
要从命令行执行此操作,可以使用名为Gifsicle的实用程序。没有内置的方法可以删除所有其他框架,因此您需要动手编写一些脚本。
这是我制作的一个快速脚本,仅需一个GIF:
#!/bin/bash
# This script will take an animated GIF and delete every other frame
# Accepts two parameters: input file and output file
# Usage: ./<scriptfilename> input.gif output.gif
# Make a copy of the file
cp $1 $2
# Get the number of frames
numframes=`gifsicle $1 -I | grep -P "\d+ images" --only-matching | grep -P "\d+" --only-matching`
# Deletion
let i=0
while [[ $i -lt $numframes ]]; do
rem=$(( $i % 2 ))
if [ $rem -eq 0 ]
then
gifsicle $2 --delete "#"$(($i/2)) -o $2
fi
let i=i+1
done
我用一个简单的倒计时GIF进行了测试:
这是通过脚本运行后的结果:
该脚本当然不是防弹的,但它可以引导您朝正确的方向前进。
gifsicle "$1" --unoptimize $(seq -f "#%g" 0 2 $numframes) -O2 -o "$2"
只需一个调用即可完成循环。
chmod +x gifdrop.sh
下面是使用一个简单的解决方案gifsicle比JohnB的脚本:
gifsicle -U input.gif `seq -f "#%g" 0 2 99` -O2 -o output.gif
该命令应该在大多数Unix shell中都可以使用。我已经在bash中对其进行了测试。用输入和输出文件名以及动画中的帧数替换input.gif
和。(可以使用更大的数字,但是gifsicle会对此抱怨。)output.gif
99
一些注意事项:
该-U
交换机将与前面的那些输入动画合并帧,使每帧代表单独的,并不依赖于任何人。您真的想在对动画进行几乎所有操作之前先执行此操作,否则您可能会得到混乱的结果。(如果您的输入动画尚未进行优化,则gifsicle可能会对此发出警告,但这完全是无害的。)
相反,该-O2
开关会重新优化输出动画以最小化文件大小。使用JohnB的示例动画,它可以将输出大小缩小27%。
该seq
命令仅输出一个从0到99的数字序列,以2为步长进行计数。-f "#%g"
使该命令#
在每个数字之前打印一个,这使gifsicle将其理解为帧选择而不是文件名。`
seq命令周围的反引号()导致其输出作为参数包含在gifsicle命令行中。
如果您不希望gif加快速度,则可以使用gifsicle -I input.gif
来获取当前的帧延迟,将其乘以2并使用gifsicle -d ${delay} ...
。
gifsicle input.gif `seq -f "#%g" 0 2 $(identify input.gif | tail -1 | cut -d "[" -f2 - | cut -d "]" -f1 -)` --unoptimize -O2 -o output.gif
useless unoptimization-related input option
。因此,我分两步(从Git Bash内部)进行了操作:1. gifsicle -U -o unoptimized.gif input.gif
2.gifsicle unoptimized.gif `seq -f "#%g" 0 2 99` -O2 -o output.gif
这是我使用批处理脚本处理的解决方案...
首先将捕获的原始动画gif复制到input.gif文件中,然后启动命令解释器并键入:
gifsicle input.gif -I“#-1”> input.txt
查看input.txt,看看动画的长度是多少-它包含多少帧...
input.txt:
* input.gif 166 images
logical screen 1366x768
global color table [256]
background 15
loop forever
+ image #165 1x1 at 1365,767 transparent 15
disposal asis delay 0.07s
然后编辑创建test.bat并更改变量len = specify_length_number_from_input.txt的值并保存test.bat ...
test.bat:
@echo off
set /A len=166
set /A i=1
set /A ii=0
:loop
if %i%==%len% goto :eof
if %ii%==0 (set /A ii=1) else (set /A ii=0)
set /A iii=%ii%*%i%
if %i%==%iii% echo gifsicle -b input.gif --delete "#1" --done
set /A i=%i%+1
goto :loop
然后最终启动process1.bat和process2.bat,并将每个奇数帧的裁剪后的动画处理到文件input.gif中。
process1.bat:
gifsicle -b -U input.gif
test.bat > input.bat
process2.bat:
call "input.bat"
gifsicle -b -O2 input.gif
erase "input.bat"
我认为我需要新的更复杂的解释(帧延迟也是也应考虑的重要问题)...对于此新过程,您需要从以下链接下载JREPL.BAT:http : //www.dostips.com /forum/viewtopic.php?t=6044
首先将捕获的gif复制到input.gif文件中,然后启动命令解释器并键入:
gifsicle input.gif -I“#-1”> input.txt
查看input.txt,看看动画的长度是多少-它包含多少帧...,还查看帧的延迟,如果其值为0.07s,则意味着您应该在此行中放入-d14选项(7msec * 2)在process.cmd中:gifsicle -b -U -d14 input.gif,编辑后保存process.cmd
然后编辑test.bat并从此行更改变量166的值以匹配动画的帧数:对于/ L %% i IN(1,2,166)DO echo“#%% i” >> input.bat,之后编辑保存test.bat ...
然后启动process.cmd,每个奇数帧的裁剪后的动画将被处理成文件input.gif
PS此方法的优点还在于,您可以完全控制要从gif中删除的内容(每第二帧(1,2,166)或每三帧(1,3,166)),依此类推,只需更改批处理行,但是请注意,如果您指定(1,3,166),则应从process.cmd中相应地更改-d14(延迟选项)以反映更改(7msec * 3/2 = 10),而不是(7msec * 2) / 1 = 14),延迟选项应为-d10 ...
其他文件(例如,每隔一帧删除一次):test.bat:
@echo off
echo gifsicle -b input.gif --delete>> input.bat
for /L %%i IN (1,2,166) DO echo "#%%i">> input.bat
echo --done>> input.bat
call jrepl.bat "\n" "" /x /m /f input.bat /o -
process.cmd:
gifsicle -b -U -d14 input.gif
call "test.bat"
call "input.bat"
gifsicle -b -O3 input.gif
erase "input.bat"
和帮助程序自述文件input.txt:
* input.gif 166 images
logical screen 1366x768
global color table [256]
background 15
loop forever
+ image #165 1x1 at 1365,767 transparent 15
disposal asis delay 0.07s
let i=0; while [[ $i -lt $(($numframes / 2)) ]]; do gifsicle $2 --delete "#$i" -o $2; let i=i+1; done