node 在图片上叠加 gif 图边框,让图片动起来

2 阅读1分钟

image.png

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;
}