node侧进行拆帧的库 gif-frames
,但是这个库是支持浏览器端,在node侧需要有另外的操作。
const { createCanvas, loadImage } = require('canvas')
const GIFEncoder = require('gifencoder');
const gifFrames = require('gif-frames');
async function imgAddGif(jpgImagePath, gifImagePath, width = 220, height = 220) {
// 创建canvas和绘图上下文
const canvas = createCanvas(width, height);
const ctx = canvas.getContext('2d');
// 初始化GIFEncoder
const encoder = new GIFEncoder(width, height);
encoder.start();
encoder.setRepeat(0); // 设置为0表示GIF循环
encoder.setQuality(10); // 图像质量
// 载入JPG图片
const myImg = await loadImage(jpgImagePath);
// 获取GIF的帧数据,这里如果设置 outputType:canvas,会报错document is not define。看 gifFrames 库的源码,使用canvas的时候用了 new Image,这个在node并不存在,因此只要进行正常的bufferArray输出,然后用 Buffer 进行转换,用node canvas loadImage 进行转换成canvas格式。
const framesData = await gifFrames({ url: gifImagePath, frames: 'all'})
for (let i = 0; i < framesData.length; i++) {
const gifFrameData = framesData[i].getImage(); // 获取当前GIF帧的画布
const gifFrame = await loadImage(Buffer.from(gifFrameData._obj));
// 在背景上绘制GIF的当前帧
ctx.drawImage(gifFrame, 0, 0, width, height);
// 绘制JPG为背景
ctx.drawImage(myImg, 4, 4, width - (4 * 2), height - (4 * 2));
// 添加帧到GIFEncoder
encoder.addFrame(ctx);
}
encoder.finish(); // 完成GIF编码
// 获取生成GIF的buffer,并写入文件系统
const buffer = encoder.out.getData();
return buffer;
}