I’ve built an algorithm that:
- Reads an image from a file using
jimp
. - Prints some text in that image and overlays another image, both using
jimp
too. - Then, using
gifwrap
, it decodes an existing GIF into all of its images, converts them toJimp
objects, and then resizes them. Afterwards, it overlays them into the previously created image (also usingjimp
). - I then try to encode all of these images into one GIF using
gifwrap
but I get the following error:FRAME 0 USES MORE THAN 256 COLOR INDEXES
public async generate() {
await this._createBaseLayer();
const frames: GifFrame[] = [];
const nftGIF = await GifUtil.read(path.join(__dirname, '../gifs/monkey.gif')).catch(reason => {
throw {
message: reason,
extraInfo: 'COULD NOT READ MONKEY GIF FILE',
};
});
for (const frame of nftGIF.frames) {
const baseLayer = this._baseLayer.clone();
const jimpCopy: Jimp = GifUtil.copyAsJimp(Jimp, frame);
jimpCopy.contain(this._measurements.nftGIF.width, this._measurements.nftGIF.height);
baseLayer.blit(jimpCopy, (this._measurements.base.width - this._measurements.nftGIF.width) / 2, (this._measurements.base.height - this._measurements.nftGIF.height - 50) / 2);
const gifFrame = new GifFrame(jimpCopy.bitmap);
GifUtil.quantizeDekker(gifFrame, 256); //THIS TAKES FOREVER
frames.push(gifFrame);
}
const codec = new GifCodec();
const gif = await codec.encodeGif(frames, {
loops: 0,
});
this._buffer = gif.buffer;
}
private async _createBaseLayer() {
const baseImage = await Jimp.read(path.join(__dirname, '../shapes/speech.png')).catch(reason => {
throw {
message: reason,
extraInfo: 'COULD NOT READ SPEECH SHAPE FILE',
};
});
const profileImage = await Jimp.read(this._user.profileImageURL).catch(reason => {
throw {
message: reason,
extraInfo: 'COULD NOT READ PROFILE IMAGE FILE',
};
});
baseImage.blit(
profileImage,
this._measurements.userIdentification.margins.left,
this._measurements.base.height - this._measurements.userIdentification.profileImage.height - this._measurements.userIdentification.margins.bot,
);
const font = await Jimp.loadFont(Jimp.FONT_SANS_32_WHITE).catch(reason => {
throw {
message: reason,
extraInfo: 'COULD NOT LOAD FONT',
};
});
baseImage.print(
font,
this._measurements.userIdentification.margins.left + this._measurements.userIdentification.profileImage.width + this._measurements.userIdentification.profileImage.margins.right,
this._measurements.base.height - this._measurements.userIdentification.profileImage.height - this._measurements.userIdentification.margins.bot,
this._user.username,
);
this._baseLayer = baseImage;
}
I have found a couple of users on the GitHub repository with the same issue:
- Error: Frame 0 uses more than 256 color indexes
- Frame 0 uses more than 256 color indexes
- Frame 1 uses more than 256 color indexes
The only “solution” I’ve found is to call quantizeDekker
on each of the GifFrames
created from the Jimp
objects (for each frame of the GIF), but it is extremely slow.