I am struggling to create a gif using the sharp library in nodejs. I am able to successfully create the frame-images that I want to use for the gif, but am not able to use them to create a gif. I am not sure if sharp even supports what I want to do, as I am getting an error when passing the frames as an array, which I thought was the right way to do this?

//Convert frames to GIF animationconst image = sharp([imagel, image2] {animated: true,}).gif(f{ loop: 0 }).toBuffer();

Error on executing node:

/usr/local/bin/node ./server.jsServer running on port 3000Process exited with code 1Uncaught Error Error: Unsupported input '?PNGIHDR ?? e??? pHYS 0 0 Q[Rk [email protected] EOOOZLAJ Q00!@(AJ Q00 !@(AJ 000 !@(A J 000 !@CAJ 000 !@CA
1

Best Answer


Unsupported input '?PNG

This could mean the PNG format is not a valid input for that gif function

It can be used to convert other (already) animated images to an animated gif, but since PNG is not animated, you would get that error.

You might need to use instead gifencoder + canvas (npm install gifencoder canvas).
Something like:

const fs = require('fs');const path = require('path');const Canvas = require('canvas');const GIFEncoder = require('gifencoder');const sharp = require('sharp');// Define the output path for the GIF.const outputPath = 'animated.gif';// Define the input PNG files.const inputFiles = ['image1.png', 'image2.png', 'image3.png'];// Create a GIFEncoder instance.const encoder = new GIFEncoder(500, 500); // Change the dimensions as needed.// Pipe the encoder output to a writable stream.const output = fs.createWriteStream(outputPath);encoder.pipe(output);// Start encoding.encoder.start();// Loop through the input files.inputFiles.forEach(async (file) => {// Convert each PNG to a raw RGBA buffer.const data = await sharp(file).raw().toBuffer();// Create a new Canvas instance.const canvas = Canvas.createCanvas(500, 500); // Change the dimensions as needed.const ctx = canvas.getContext('2d');// Create an ImageData instance from the raw RGBA buffer.const imageData = new Canvas.ImageData(new Uint8ClampedArray(data),canvas.width,canvas.height);// Put the ImageData instance into the canvas.ctx.putImageData(imageData, 0, 0);// Add the frame to the GIF.encoder.addFrame(ctx);});// Finish encoding.encoder.finish();

That would read each PNG file, converts it to a raw RGBA buffer using sharp, puts the image data into a canvas, and then adds the canvas as a frame to the GIF using gifencoder.