6

I was surprised today to find apparently how difficult it is to go from a webp animation to gif animation. My GIMP 2.8.22 and ImageMagick 7.0.7-21 on linux 4.14.13-1-ARCH don't seem to support the format, and the only tool available in repos seem to be libwebp 0.4.1 which includes a decode tool that lets you extract individual frames to some image formats, none of them being gif (It's a licensing problem maybe?)

Anyway, I used the following script:

#!/bin/bash

DELAY=${DELAY:-10}
LOOP=${LOOP:-0}
r=`realpath $1`
d=`dirname $r`
pushd $d > /dev/null
f=`basename $r`
n=`webpinfo -summary $f | grep frames | sed -e 's/.* \([0-9]*\)$/\1/'`
pfx=`echo -n $f | sed -e 's/^\(.*\).webp$/\1/'`
if [ -z $pfx ]; then
    pfx=$f
fi

echo "converting $n frames from $f 
working dir $d
file stem '$pfx'"

for ((i=0; i<$n; i++)); do
    webpmux -get frame $i $f -o $pfx.$i.webp
    dwebp $pfx.$i.webp -o $pfx.$i.png
done

convert $pfx.*.png -delay $DELAY -loop $LOOP $pfx.gif
rm $pfx.[0-9]*.png $pfx.[0-9]*.webp
popd > /dev/null

Which creates a gif animation from the extracted frames of the file supplied in the first argument.

I tried it on this file and the resulting file was kind of artifacty. Is it proper form to post in this forum for suggestions of improvement of the procedure/invocations?

And: If there are custom tools for this conversion, please share your knowledge! :)

  • 1
    This seems like a question better suited for Code Review (still not off topic!) – Stan Strum Jan 26 '18 at 17:13
  • I would think keep it here because *nix users wondering about this conversion would have a better change finding it here and thus benefit from the discussion? – lash Jan 26 '18 at 17:29
3

Your script works just fine, but you need to zero pad your individual frame names; otherwise it creates the gif with frames in a jumbled order. I fixed that and tried it on a few giphy webp animations (including your example) and the output is what you'd expect.

Below is just your script with two changes. First, an altered for loop to zero pad those frame filenames. Second, I added another webpinfo check to grab the frame duration and use that (if > 0) for DELAY (naively assuming that people aren't using variable frame durations):

#!/bin/bash

DELAY=${DELAY:-10}
LOOP=${LOOP:-0}
r=`realpath $1`
d=`dirname $r`
pushd $d > /dev/null
f=`basename $r`
n=`webpinfo -summary $f | grep frames | sed -e 's/.* \([0-9]*\)$/\1/'`
dur=`webpinfo -summary $f | grep Duration | head -1 |  sed -e 's/.* \([0-9]*\)$/\1/'`

if (( $dur > 0 )); then
    DELAY = dur
fi

pfx=`echo -n $f | sed -e 's/^\(.*\).webp$/\1/'`
if [ -z $pfx ]; then
    pfx=$f
fi

echo "converting $n frames from $f 
working dir $d
file stem '$pfx'"

for i in $(seq -f "%05g" 1 $n)
do
    webpmux -get frame $i $f -o $pfx.$i.webp
    dwebp $pfx.$i.webp -o $pfx.$i.png
done

convert $pfx.*.png -delay $DELAY -loop $LOOP $pfx.gif
rm $pfx.[0-9]*.png $pfx.[0-9]*.webp
popd > /dev/null
2

I would have used ffmpeg for this task. Have a look at this thread which should give you good results.

I tried with the mp4 of the gif from giphy and obtained this gif below as a result, which looks pretty good in my opinion!

mkdir frames
ffmpeg -i giphy.mp4 -vf scale=320:-1:flags=lanczos,fps=10 frames/ffout%03d.png
convert -loop 0 frames/ffout*.png output.gif

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.