Corrected combining durations from multiple frames into single frame

This commit is contained in:
Andrew Murray 2023-11-03 21:09:16 +11:00
parent 1c2f2c79e1
commit dc0379fea5
2 changed files with 30 additions and 23 deletions

View File

@ -856,7 +856,14 @@ def test_identical_frames(tmp_path):
@pytest.mark.parametrize(
"duration", ([1000, 1500, 2000, 4000], (1000, 1500, 2000, 4000), 8500)
"duration",
(
[1000, 1500, 2000],
(1000, 1500, 2000),
# One more duration than the number of frames
[1000, 1500, 2000, 4000],
1500,
),
)
def test_identical_frames_to_single_frame(duration, tmp_path):
out = str(tmp_path / "temp.gif")
@ -872,7 +879,7 @@ def test_identical_frames_to_single_frame(duration, tmp_path):
assert reread.n_frames == 1
# Assert that the new duration is the total of the identical frames
assert reread.info["duration"] == 8500
assert reread.info["duration"] == 4500
def test_loop_none(tmp_path):

View File

@ -627,28 +627,28 @@ def _write_multiple_frames(im, fp, palette):
bbox = None
im_frames.append({"im": im_frame, "bbox": bbox, "encoderinfo": encoderinfo})
if len(im_frames) > 1:
for frame_data in im_frames:
im_frame = frame_data["im"]
if not frame_data["bbox"]:
# global header
for s in _get_global_header(im_frame, frame_data["encoderinfo"]):
fp.write(s)
offset = (0, 0)
else:
# compress difference
if not palette:
frame_data["encoderinfo"]["include_color_table"] = True
if len(im_frames) == 1:
if "duration" in im.encoderinfo:
# Since multiple frames will not be written, use the combined duration
im.encoderinfo["duration"] = im_frames[0]["encoderinfo"]["duration"]
return
im_frame = im_frame.crop(frame_data["bbox"])
offset = frame_data["bbox"][:2]
_write_frame_data(fp, im_frame, offset, frame_data["encoderinfo"])
return True
elif "duration" in im.encoderinfo and isinstance(
im.encoderinfo["duration"], (list, tuple)
):
# Since multiple frames will not be written, add together the frame durations
im.encoderinfo["duration"] = sum(im.encoderinfo["duration"])
for frame_data in im_frames:
im_frame = frame_data["im"]
if not frame_data["bbox"]:
# global header
for s in _get_global_header(im_frame, frame_data["encoderinfo"]):
fp.write(s)
offset = (0, 0)
else:
# compress difference
if not palette:
frame_data["encoderinfo"]["include_color_table"] = True
im_frame = im_frame.crop(frame_data["bbox"])
offset = frame_data["bbox"][:2]
_write_frame_data(fp, im_frame, offset, frame_data["encoderinfo"])
return True
def _save_all(im, fp, filename):