Remove nth frames of a gif (remove a frame every n frames)

animationffmpeggifimagemagickvideo

I've recorded a .gif of the screen with ffmpeg. I've used gifsicle and imagemagick to compress it a bit, but it's still to big. My intent is making it small by removing, say, a frame every 2 frames, so that the total count of frames will be halved.

I couldn't find a way to do it, neither with gifsicle nor with imagemagick. man pages didn't help.

How can I remove a frame from a .gif animation every n frames?

Best Answer

There is probably a better way to do it, but here is what I would do

First, split your animation in frames

convert animation.gif +adjoin temp_%02d.gif

Then, select one over n frames with a small for-loop in which you loop over all the frames, you check if it is divisible by 2 and if so you copy it in a new temporary file.

j=0; for i in $(ls temp_*gif); do if [ $(( $j%2 )) -eq 0 ]; then cp $i sel_`printf %02d $j`.gif; fi; j=$(echo "$j+1" | bc); done

If you prefer to keep all the non-divisible numbers (and so if you want to delete rather than to keep every nth frame), replace -eq by -ne.

And once you done it, create your new animation from the selected frames

convert -delay 20 $( ls sel_*) new_animation.gif

You can make a small script convert.sh easily, which would be something like that

#!/bin/bash
animtoconvert=$1
nframe=$2
fps=$3

# Split in frames
convert $animtoconvert +adjoin temp_%02d.gif

# select the frames for the new animation
j=0
for i in $(ls temp_*gif); do 
    if [ $(( $j%${nframe} )) -eq 0 ]; then 
        cp $i sel_`printf %02d $j`.gif; 
    fi; 
    j=$(echo "$j+1" | bc); 
done

# Create the new animation & clean up everything
convert -delay $fps $( ls sel_*) new_animation.gif
rm temp_* sel_*

And then just call, for example

$ convert.sh youranimation.gif 2 20
Related Question