webp 动画转 gif 动画 (cli)

webp 动画转 gif 动画 (cli)

今天我很惊讶地发现从一个webp动画到gif另一个动画显然是多么困难。我的GIMP 2.8.22ImageMagick 7.0.7-21onlinux 4.14.13-1-ARCH似乎不支持该格式,并且存储库中唯一可用的工具似乎libwebp 0.4.1包括一个解码工具,可以让您将单个帧提取为某些图像格式,但它们都不是 gif (这可能是许可问题? )

无论如何,我使用了以下脚本:

#!/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

它根据第一个参数中提供的文件的提取帧创建 gif 动画。

我试穿了这个文件结果文件有点人工。在这个论坛上发布改进程序/调用的建议是否合适?

并且:如果有用于此转换的自定义工具,请分享您的知识! :)

答案1

我自己也遇到了同样的问题,我发现使用 Python 及其 Pillow 库可能是最简单的方法。只需导入它,让它加载图像文件,然后使用适当的选项直接再次保存即可。

from PIL import Image
im = Image.open('your_file.webp')
im.save('your_file.gif', 'gif', save_all=True, optimize=True, background=0)

使用 Python3.8 和 Pillow 8.0.1 进行测试。您可能必须首先安装或升级库,使用例如python3 -m pip install --user --upgrade Pillow

一行一行将*.webp当前文件夹中的所有文件批量转换为*.gif同名文件:

for f in *.webp;do echo "$f";python3 -c "from PIL import Image;Image.open('$f').save('${f%.webp}.gif','gif',save_all=True,optimize=True,background=0)";done

注:此答案的灵感来自堆栈溢出

答案2

您的脚本工作得很好,但您需要对各个帧名称进行零填充;否则,它会创建帧顺序混乱的 gif。我修复了这个问题,并在一些 giphy webp 动画(包括您的示例)上进行了尝试,输出正是您所期望的。

下面只是您的脚本,有两处更改。首先,更改for循环以对这些帧文件名进行零填充。其次,我添加了另一个 webpinfo 检查来获取帧持续时间并使用它(如果 > 0)进行延迟(天真地假设人们没有使用可变帧持续时间):

#!/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

答案3

我会用来ffmpeg完成这项任务。看一下这个线程这应该会给你带来好的结果。

我尝试使用来自 giphy 的 gif 的 mp4 并获得下面的这个 gif 结果,在我看来这看起来相当不错!

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

在此输入图像描述

答案4

大部分脚本可以使用anim_dump二进制文件替换,该二进制文件包含在libwebp包裹以及webpmuxdwebp

#!/bin/bash

for file in /path/to/*.webp; do
    mkdir "$temporaryDirectory.frames"

    # export a webp file into frames;
    # Download the packge directly from the official Google Analytics repository in
    # http://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.3.0-linux-x86-64.tar.gz
    anim_dump -folder "$temporaryDirectory.frames" "$file"

    convert "$temporaryDirectory.frames"/*.png -delay 10 -loop 0 "$file.gif"
    /bin/rm -fr "$temporaryDirectory.frames"
done

相关内容