环境:

环境:

我希望能够改变动态 webp 的大小。 示例图片。 我发现本网站就能做到这一点。

那么我如何在自己的程序中实现类似的东西?我尝试使用 ImageMagick7 或 ffmpeg5,但失败了。

环境:

cat /etc/redhat-release:CentOS Linux 版本 7.8.2003(核心)

1.尝试了ffmpeg:

[developer@Dev_Payment_229 ~]$ /opt/ffmpeg-5/ffmpeg -i b.webp -vf "scale=320:-1" b_320.webp
ffmpeg version 5.1.1-static https://johnvansickle.com/ffmpeg/  Copyright (c) 2000-2022 the FFmpeg developers
  built with gcc 8 (Debian 8.3.0-6)
  configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gmp --enable-libgme --enable-gray --enable-libaom --enable-libfribidi --enable-libass --enable-libvmaf --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libdav1d --enable-libxvid --enable-libzvbi --enable-libzimg
  libavutil      57. 28.100 / 57. 28.100
  libavcodec     59. 37.100 / 59. 37.100
  libavformat    59. 27.100 / 59. 27.100
  libavdevice    59.  7.100 / 59.  7.100
  libavfilter     8. 44.100 /  8. 44.100
  libswscale      6.  7.100 /  6.  7.100
  libswresample   4.  7.100 /  4.  7.100
  libpostproc    56.  6.100 / 56.  6.100
[webp @ 0x7686f40] skipping unsupported chunk: ANIM
[webp @ 0x7686f40] skipping unsupported chunk: ANMF
    Last message repeated 10 times
[webp @ 0x7686f40] image data not found
[webp_pipe @ 0x7685700] Could not find codec parameters for stream 0 (Video: webp, none): unspecified size
Consider increasing the value for the 'analyzeduration' (0) and 'probesize' (5000000) options
Input #0, webp_pipe, from 'b.webp':
  Duration: N/A, bitrate: N/A
  Stream #0:0: Video: webp, none, 25 fps, 25 tbr, 25 tbn
Stream mapping:
  Stream #0:0 -> #0:0 (webp (native) -> webp (libwebp_anim))
Press [q] to stop, [?] for help
[webp @ 0x7697600] skipping unsupported chunk: ANIM
[webp @ 0x7697600] skipping unsupported chunk: ANMF
    Last message repeated 10 times
[webp @ 0x7697600] image data not found
Error while decoding stream #0:0: Invalid data found when processing input
Cannot determine format of input stream 0:0 after EOF
Error marking filters as finished
Conversion failed!

看来ffmpeg无法识别这个动态的WebP图像。

2.尝试过 ImageMagick7

安装:

 yum -y install libwebp-devel libwebp-tools
[root@Dev_FTP_241 developer]# yum list installed | grep webp
libwebp.x86_64                         0.3.0-11.el7               @updates
libwebp-devel.x86_64                   0.3.0-11.el7               @updates
libwebp-tools.x86_64                   0.3.0-11.el7               @updates

源代码:

https://github.com/ImageMagick/ImageMagick/archive/refs/tags/7.1.1-0.tar.gz
tar -xvf ImageMagick-7.1.1-0.tar.gz
./configure --with-webp --prefix=/usr/local/imagemagick
make
make install

单个 WebP 可以调整大小:

[root@Dev_FTP_241 developer]#  /usr/local/imagemagick/bin/convert -resize 480  simple.webp simple_480.webp
Decoded /tmp/magick-LNPdXgk2zDpiuU6Qv9CpDups3560EATh. Dimensions: 2160 x 608. Now saving...
Saved file /tmp/magick-Q8JHRZZOXdp1r1x187eftzsFlw8AqAuo

但动画 WebP 失败了:

[root@Dev_FTP_241 developer]#  /usr/local/imagemagick/bin/convert -resize 480  b.webp b_480.webp
Error! Decoding of an animated WebP file is not supported.
       Use webpmux to extract the individual frames or
       vwebp to view this image.
Decoding of /tmp/magick-jMiy7ytmAnBzpS8UpafCQ5B44BjDTUSD failed.
Status: 4 (UNSUPPORTED_FEATURE)
convert: delegate failed `'dwebp' -pam '%i' -o '%o'' @ error/delegate.c/InvokeDelegate/1924.
convert: unable to open file '/tmp/magick-D-NMEGWU_a0IypZWwTpYiWIE61nteoig': No such file or directory @ error/constitute.c/ReadImage/786.
convert: no images defined `b_480.webp' @ error/convert.c/ConvertImageCommand/3342.

答案1

Google 的 cwebp 可以调整 WebP 图像的大小,但奇怪的是不能调整动画图像的大小。

我成功尝试了锋利的,这是一个基于利维普

也许重新缩放可以通过libvips 命令行界面如果不是,示例 sharp 脚本(使用 node.js 运行)可能如下所示:

#!/usr/bin/env node

import * as fs from 'node:fs';
import sharp from 'sharp';

const dir = await fs.promises.opendir('./source');
const buffers = [];
for await (const dirent of dir) {
  if (dirent.isFile()) {
    buffers.push([
      dirent.name, fs.createReadStream('./source/'+dirent.name),
    ]);
  }
}

const width = 128; // change to your target width

await fs.promises.mkdir('./resized/');

for (const _buf of buffers) {
  const pipeline = sharp({ pages: -1, })
    .resize({ width, height: width, fit: 'inside' })
    .toFile('./resized/'+_buf[0]);

  try {
    await _buf[1].pipe(pipeline);
  } catch (e) {
    console.log('problem: '+e);
  }
}

答案2

ffmpeg似乎没有从今天起支持.webp一般解码。

ImageMagick 具有此功能。您需要确保在您的系统中可用,并且您的 ImageMagick 构建已启用 WebP 支持。然后使用这个命令对我有用:

magick input.webp -resize 50% -layers coalesce output.webp

-layers coalesce需要标准化框架,否则会出现框架尺寸错误。

答案3

对于我来说,图像魔法是有效的,但你必须输入百分比的调整大小选项,否则 webp 会失去动画。

因此,如果原始尺寸为 512x512 而您想要 480x480,则必须先进行一些简单的计算:

480/512 * 100 = 93,75%

magick b_512.webp -resize 93.75% b_480.webp

您必须使用点而不是逗号作为小数分隔符......

答案4

使用 Python 脚本

安装python:

yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel libjpeg-turbo-devel readline-devel tk-devel gcc make

wget https://www.python.org/ftp/python/3.9.9/Python-3.9.9.tgz

tar -zxvf Python-3.9.9.tgz

cd Python-3.9.9

./configure --prefix=/usr/local/python3.9
make
make install

/usr/local/python3.9/bin/python3 -V
/usr/local/python3.9/bin/pip3 -V

安装枕头:

/usr/local/python3.9/bin/pip3 install pillow==9.5.0

创建.py: vi resize.py

# coding:utf-8
# resize.py
import sys
from PIL import Image, ImageSequence

try:
    height = int(sys.argv[1])
    input_file = sys.argv[2]
    output_file = sys.argv[3]
except IndexError:
    print('Usage: python resize.py <height> <input_file> <output_file>')
    print('Example: python resize.py 400 input.webp output.webp')
    sys.exit(1)

# 加载动态 WebP 图像
image = Image.open(input_file)

# 计算新的高度(保持原始宽高比)
orig_width, orig_height = image.size
width = int(orig_width * (height / orig_height))
if height <= 0:
    width = orig_width
    height = orig_height

# 获取所有帧数据
frames = []
for frame in ImageSequence.Iterator(image):
    frames.append(frame.copy())

if len(frames) > 1:
    # print('多张')
    # 缩放每个帧
    new_frames = []

    first_frame = frames[0]

    for i in range(len(frames)):
        new_frame = frames[i].resize((width, height))
        new_frames.append(new_frame)

    # 将动画 图像另存为文件
    new_frames[0].save(
        output_file,
        save_all=True,
        append_images=new_frames[1:],
    )

else:
    # print('单张')
    # 缩放图像
    new_img = image.resize((width, height))
    # 保存新图像
    new_img.save(output_file)

测试:

/usr/local/python3.9/bin/python3 resize.py 260  animated.webp ani_resize260.webp

相关内容