How to add watermark to an animated gif image using jimp javascript?
Solution 1:
Confusingly, Jimp only deals with single frame GIFs, not the multi-frame animated GIFs that most people think of. So you need to use gifwrap.
From there you could iterate over each frame in the multi-frame GIF. Each frame is a GifFrame
, which can be converted back and forth to a Jimp instance (see Leveraging Jimp in the docs). You can add your watermark to each Jimp instance that corresponds to a GifFrame
. Something like this:
async function getGifFramesWithWatermarks(gifPath) {
const readGif = await GifUtil.read(gifPath);
const promises = readGif.frames.map(getGifFrameWithWatermark);
const gifFramesWithWatermarks = await Promise.all(promises);
return gifFramesWithWatermarks;
}
async function getGifFrameWithWatermark(gifFrame) {
const jimpImage = GifUtil.copyAsJimp(Jimp, gifFrame);
addWatermark(jimpImage); // function you will write
return new GifFrame(jimpImage.bitmap, {
disposalMethod: gifFrame.disposalMethod, // not documented by gifwrap but it's in the source
delayCentisecs: gifFrame.delayCentisecs, // you'll probably want this
});
}
const gifFramesWithWatermarks = await getGifFramesWithWatermark(GIF_PATH);
await GifUtil.write(WRITE_PATH, gifFramesWithWatermarks);
Solution 2:
UPDATE i wrote this npm library that you can use to write text on gif. its still has some bugs tho: https://www.npmjs.com/package/text-on-gif
this worked for me
const Jimp = require("jimp");
const { GifUtil,GifFrame,BitmapImage} = require('gifwrap');
var frames = [];
Jimp.loadFont(Jimp.FONT_SANS_32_WHITE).then(async function(font){
await GifUtil.read("gif.gif").then(inputGif => {
inputGif.frames.forEach(function(frame){
jimpCopied = GifUtil.copyAsJimp(Jimp, frame);
jimpCopied.print(font,0,0,"sanidhya");
const GifCopied = new GifFrame(new BitmapImage(jimpCopied.bitmap,{
disposalMethod: frame.disposalMethod,
delayCentisecs: frame.delayCentisecs,
}));
frames.push(GifCopied);
});
});
GifUtil.quantizeDekker(frames);
GifUtil.write("nyahhaha.gif",frames);
});
NOTE
the qunatize*() function is needed only if your Frame uses more than 256 color indexes