mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 02:30:12 +02:00
Ensure animated GIF to WebP conversion retains loop #3394
This commit is contained in:
parent
38b6f44611
commit
701143afb3
@ -8,6 +8,9 @@ Requires libvips v8.16.1
|
||||
|
||||
### v0.34.2 - TBD
|
||||
|
||||
* Ensure animated GIF to WebP conversion retains loop (regression in 0.34.0).
|
||||
[#3394](https://github.com/lovell/sharp/issues/3394)
|
||||
|
||||
* Ensure `pdfBackground` constructor property is used.
|
||||
[#4207](https://github.com/lovell/sharp/pull/4207)
|
||||
|
||||
|
@ -298,7 +298,7 @@ const Sharp = function (input, options) {
|
||||
withExif: {},
|
||||
withExifMerge: true,
|
||||
resolveWithObject: false,
|
||||
loop: 1,
|
||||
loop: -1,
|
||||
delay: [],
|
||||
// output format
|
||||
jpegQuality: 80,
|
||||
|
@ -651,22 +651,21 @@ namespace sharp {
|
||||
*/
|
||||
VImage SetAnimationProperties(VImage image, int nPages, int pageHeight, std::vector<int> delay, int loop) {
|
||||
bool hasDelay = !delay.empty();
|
||||
|
||||
// Avoid a copy if none of the animation properties are needed.
|
||||
if (nPages == 1 && !hasDelay && loop == -1) return image;
|
||||
|
||||
if (delay.size() == 1) {
|
||||
// We have just one delay, repeat that value for all frames.
|
||||
delay.insert(delay.end(), nPages - 1, delay[0]);
|
||||
}
|
||||
|
||||
// Attaching metadata, need to copy the image.
|
||||
VImage copy = image.copy();
|
||||
|
||||
// Only set page-height if we have more than one page, or this could
|
||||
// accidentally turn into an animated image later.
|
||||
if (nPages > 1) copy.set(VIPS_META_PAGE_HEIGHT, pageHeight);
|
||||
if (hasDelay) copy.set("delay", delay);
|
||||
if (hasDelay) {
|
||||
if (delay.size() == 1) {
|
||||
// We have just one delay, repeat that value for all frames.
|
||||
delay.insert(delay.end(), nPages - 1, delay[0]);
|
||||
}
|
||||
copy.set("delay", delay);
|
||||
}
|
||||
if (nPages == 1 && !hasDelay && loop == -1) {
|
||||
loop = 1;
|
||||
}
|
||||
if (loop != -1) copy.set("loop", loop);
|
||||
|
||||
return copy;
|
||||
|
@ -384,7 +384,7 @@ struct PipelineBaton {
|
||||
ensureAlpha(-1.0),
|
||||
colourspacePipeline(VIPS_INTERPRETATION_LAST),
|
||||
colourspace(VIPS_INTERPRETATION_LAST),
|
||||
loop(1),
|
||||
loop(-1),
|
||||
tileSize(256),
|
||||
tileOverlap(0),
|
||||
tileContainer(VIPS_FOREIGN_DZ_CONTAINER_FS),
|
||||
|
@ -238,4 +238,15 @@ describe('GIF input', () => {
|
||||
assert.strictEqual(1, loop);
|
||||
}
|
||||
});
|
||||
|
||||
it('Animated GIF to animated WebP merges identical frames', async () => {
|
||||
const webp = await sharp(fixtures.inputGifAnimated, { animated: true })
|
||||
.webp()
|
||||
.toBuffer();
|
||||
|
||||
const { delay, loop, pages } = await sharp(webp).metadata();
|
||||
assert.deepStrictEqual([120, 120, 90, 120, 120, 90, 120, 90, 30], delay);
|
||||
assert.strictEqual(0, loop);
|
||||
assert.strictEqual(9, pages);
|
||||
});
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user