Expose keepDuplicateFrames GIF output parameter

This commit is contained in:
Lovell Fuller
2025-06-15 15:39:01 +01:00
parent 9392b8702b
commit 8c53d499f7
9 changed files with 50 additions and 2 deletions

View File

@@ -187,6 +187,17 @@ describe('GIF input', () => {
);
});
it('invalid keepDuplicateFrames throws', () => {
assert.throws(
() => sharp().gif({ keepDuplicateFrames: -1 }),
/Expected boolean for keepDuplicateFrames but received -1 of type number/
);
assert.throws(
() => sharp().gif({ keepDuplicateFrames: 'fail' }),
/Expected boolean for keepDuplicateFrames but received fail of type string/
);
});
it('should work with streams when only animated is set', function (done) {
fs.createReadStream(fixtures.inputGifAnimated)
.pipe(sharp({ animated: true }))
@@ -225,6 +236,20 @@ describe('GIF input', () => {
assert.strict(before.length > after.length);
});
it('should keep duplicate frames via keepDuplicateFrames', async () => {
const create = { width: 8, height: 8, channels: 4, background: 'blue' };
const input = sharp([{ create }, { create }], { join: { animated: true } });
const before = await input.gif({ keepDuplicateFrames: false }).toBuffer();
const after = await input.gif({ keepDuplicateFrames: true }).toBuffer();
assert.strict(before.length < after.length);
const beforeMeta = await sharp(before).metadata();
const afterMeta = await sharp(after).metadata();
assert.strictEqual(beforeMeta.pages, 1);
assert.strictEqual(afterMeta.pages, 2);
});
it('non-animated input defaults to no-loop', async () => {
for (const input of [fixtures.inputGif, fixtures.inputPng]) {
const data = await sharp(input)