简体   繁体   English

在 Node.js 中制作 GIF 会导致图像损坏

[英]Making GIF in Node.js results in broken image

I am trying to make a basic gif.我正在尝试制作一个基本的 gif。 I based my code almost entirely on the sample in this NPM library .我的代码几乎完全基于这个 NPM library中的示例。 However, each time the GIF comes out as a broken image file.但是,每次 GIF 以损坏的图像文件出现。

CODE代码

const CanvasGifEncoder = require('canvas-gif-encoder');
const {createCanvas} = require('canvas');
const fs = require('fs');
const os = require('os');
const datauri = require('datauri');

exports.helloWorld = async (req, res) => {

  const canvas = createCanvas(120, 120);
  const ctx = canvas.getContext('2d');
  const encoder = new CanvasGifEncoder(120, 120);
  
  let stream = fs.createWriteStream(os.tmpdir() + "/output.gif");
  encoder.createReadStream().pipe(stream);
  
  encoder.begin();
  
  ctx.fillStyle = 'black';
  ctx.fillRect(0, 0, 120, 120);
  encoder.addFrame(ctx, 250);
  
  let colors = ['white', 'yellow', 'cyan', 'lime', 'magenta', 'red', 'blue'];
  
  for (let i = 0; i < colors.length; ++i) {
      ctx.fillStyle = colors[i];
      ctx.fillRect(i / colors.length * 120, 0, 120 / colors.length, 120);
      encoder.addFrame(ctx, 250);
  }
  
  encoder.end();

  const contentXX = await datauri(os.tmpdir() + '/output.gif');
  res.status(200).send('<img src="' + contentXX +'">');

};

RESULT结果

 <img src="data:image/gif;base64,R0lGODlheAB4AHAAACH/C05FVFNDQVBFMi4wAwEAAAA=">

EDIT编辑

I have also tried using image-data-uri instead of datauri , who's library specifies compatibility with the GIF format.我也尝试过使用image-data-uri而不是datauri ,它的库指定了与 GIF 格式的兼容性。 It yields the same results.它产生相同的结果。 For that you can try replacing the last two lines of the above code with:为此,您可以尝试将上述代码的最后两行替换为:

const imageDataURI = require('image-data-uri');

imageDataURI.encodeFromFile(os.tmpdir() + '/output.gif').then(contentXX => res.status(200).send('<img src="' + contentXX +'">'));

The streaming is async, so when you call datauri immediately after encoder.end() it hasn't finished writing the file yet.流是异步的,因此当您在 encoder.end encoder.end()之后立即调用datauri时,它还没有完成文件的写入。 Its only written a handful of bytes so thats all you get back in your base64 string.它只写了几个字节,所以这就是你在 base64 字符串中得到的所有内容。

Use the write stream's finish event to wait for the file to be written.使用写入流的finish事件来等待文件被写入。

encoder.begin();

stream.on('finish', () => {
    const contentXX = await datauri(os.tmpdir() + '/output.gif');
    res.status(200).send('<img src="' + contentXX +'">');
})

ctx.fillStyle = 'black';
//...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM