You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在React/NextJS中用JavaScript解码动效WebP并提取帧与延迟

在React/NextJS中解码动画WebP并提取帧与延迟时长

node-webpmux依赖Node.js的fs模块,仅适用于服务端,在浏览器环境(包括React/NextJS客户端)中必然崩溃,所以需要使用纯浏览器兼容的WebP解码方案。下面是具体实现步骤:

1. 选择浏览器兼容的解码库

使用libwebp-js——这是Google官方libwebp库的Wasm编译版本,完全兼容浏览器环境,支持解码动画WebP并提取帧信息。

先安装依赖:

npm install libwebp-js

2. 编写解码函数

创建一个异步函数,负责接收WebP的ArrayBuffer数据,解码后返回包含每帧图像数据和延迟时长的数组:

import libwebp from 'libwebp-js';

async function decodeAnimatedWebP(arrayBuffer) {
  // 等待Wasm模块初始化完成
  await libwebp.ready;

  const uint8Data = new Uint8Array(arrayBuffer);
  const decoder = new libwebp.WebPDecoder();
  const decodeResult = decoder.decode(uint8Data);

  if (!decodeResult.isAnimated) {
    throw new Error('当前文件不是动画WebP格式');
  }

  const frames = [];
  for (let i = 0; i < decodeResult.frameCount; i++) {
    const frame = decoder.getFrame(i);
    // 将帧数据转换为浏览器可直接使用的ImageData
    const imageData = new ImageData(
      new Uint8ClampedArray(frame.data),
      frame.width,
      frame.height
    );
    // 提取帧延迟(单位:毫秒)
    frames.push({
      imageData,
      delay: frame.delay
    });
  }

  return frames;
}

3. 在React/NextJS组件中使用

注意:由于Wasm只能在浏览器环境运行,NextJS中需要将组件标记为客户端组件(添加'use client'指令):

'use client';

import { useState } from 'react';
import libwebp from 'libwebp-js';

// 上面的decodeAnimatedWebP函数

export default function WebPDecoder() {
  const [frameData, setFrameData] = useState([]);

  const handleFileUpload = async (e) => {
    const file = e.target.files[0];
    if (!file || file.type !== 'image/webp') return;

    try {
      const arrayBuffer = await file.arrayBuffer();
      const frames = await decodeAnimatedWebP(arrayBuffer);
      setFrameData(frames);
      console.log('解码完成,共', frames.length, '帧');
    } catch (err) {
      console.error('解码失败:', err);
    }
  };

  return (
    <div>
      <input type="file" accept="image/webp" onChange={handleFileUpload} />
      {frameData.length > 0 && (
        <div>
          <h3>解码结果:{frameData.length}帧</h3>
          {frameData.map((frame, idx) => (
            <div key={idx}>
              <p>第{idx+1}帧,延迟{frame.delay}ms</p>
              <canvas
                width={frame.imageData.width}
                height={frame.imageData.height}
                ref={(canvas) => {
                  if (canvas) {
                    const ctx = canvas.getContext('2d');
                    ctx.putImageData(frame.imageData, 0, 0);
                  }
                }}
              />
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

4. 处理网络上的动画WebP

如果需要解码远程WebP图片,可通过fetch获取ArrayBuffer后传入解码函数:

async function fetchAndDecodeRemoteWebP(url) {
  const response = await fetch(url);
  if (!response.ok) throw new Error('图片请求失败');
  const arrayBuffer = await response.arrayBuffer();
  return decodeAnimatedWebP(arrayBuffer);
}

内容的提问来源于stack exchange,提问作者yondur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 08:45:46