From 7e084c7ede0e6a6c3400ad7c877f1424560e66ea Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Tue, 3 May 2022 20:07:47 +1000 Subject: [PATCH] Use durations from each frame by default when saving --- Tests/test_file_gif.py | 19 ++++++++++++++++++- src/PIL/GifImagePlugin.py | 4 +++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/Tests/test_file_gif.py b/Tests/test_file_gif.py index fd30cded0..3c2fab722 100644 --- a/Tests/test_file_gif.py +++ b/Tests/test_file_gif.py @@ -3,7 +3,7 @@ from io import BytesIO import pytest -from PIL import GifImagePlugin, Image, ImageDraw, ImagePalette, features +from PIL import GifImagePlugin, Image, ImageDraw, ImagePalette, ImageSequence, features from .helper import ( assert_image_equal, @@ -691,6 +691,23 @@ def test_multiple_duration(tmp_path): pass +def test_roundtrip_info_duration(tmp_path): + duration_list = [100, 500, 500] + + out = str(tmp_path / "temp.gif") + with Image.open("Tests/images/transparent_dispose.gif") as im: + assert [ + frame.info["duration"] for frame in ImageSequence.Iterator(im) + ] == duration_list + + im.save(out, save_all=True) + + with Image.open(out) as reloaded: + assert [ + frame.info["duration"] for frame in ImageSequence.Iterator(reloaded) + ] == duration_list + + def test_identical_frames(tmp_path): duration_list = [1000, 1500, 2000, 4000] diff --git a/src/PIL/GifImagePlugin.py b/src/PIL/GifImagePlugin.py index 80c1d63c5..9b34a3b0e 100644 --- a/src/PIL/GifImagePlugin.py +++ b/src/PIL/GifImagePlugin.py @@ -561,7 +561,7 @@ def _write_single_frame(im, fp, palette): def _write_multiple_frames(im, fp, palette): - duration = im.encoderinfo.get("duration", im.info.get("duration")) + duration = im.encoderinfo.get("duration") disposal = im.encoderinfo.get("disposal", im.info.get("disposal")) im_frames = [] @@ -579,6 +579,8 @@ def _write_multiple_frames(im, fp, palette): encoderinfo = im.encoderinfo.copy() if isinstance(duration, (list, tuple)): encoderinfo["duration"] = duration[frame_count] + elif duration is None and "duration" in im_frame.info: + encoderinfo["duration"] = im_frame.info["duration"] if isinstance(disposal, (list, tuple)): encoderinfo["disposal"] = disposal[frame_count] frame_count += 1