Merge pull request #8104 from radarhere/apng

This commit is contained in:
Hugo van Kemenade 2024-06-25 21:58:32 +03:00 committed by GitHub
commit a4188bb75e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 19 additions and 9 deletions

View File

@ -706,10 +706,21 @@ def test_different_modes_in_later_frames(
assert reloaded.mode == mode
def test_apng_repeated_seeks_give_correct_info() -> None:
def test_different_durations(tmp_path: Path) -> None:
test_file = str(tmp_path / "temp.png")
with Image.open("Tests/images/apng/different_durations.png") as im:
for i in range(3):
for _ in range(3):
im.seek(0)
assert im.info["duration"] == 4000
im.seek(1)
assert im.info["duration"] == 1000
im.save(test_file, save_all=True)
with Image.open(test_file) as reloaded:
assert reloaded.info["duration"] == 4000
reloaded.seek(1)
assert reloaded.info["duration"] == 1000

View File

@ -1115,7 +1115,7 @@ class _fdat:
def _write_multiple_frames(im, fp, chunk, mode, rawmode, default_image, append_images):
duration = im.encoderinfo.get("duration", im.info.get("duration", 0))
duration = im.encoderinfo.get("duration")
loop = im.encoderinfo.get("loop", im.info.get("loop", 0))
disposal = im.encoderinfo.get("disposal", im.info.get("disposal", Disposal.OP_NONE))
blend = im.encoderinfo.get("blend", im.info.get("blend", Blend.OP_SOURCE))
@ -1136,6 +1136,8 @@ def _write_multiple_frames(im, fp, chunk, mode, rawmode, default_image, append_i
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]
if isinstance(blend, (list, tuple)):
@ -1170,15 +1172,12 @@ def _write_multiple_frames(im, fp, chunk, mode, rawmode, default_image, append_i
not bbox
and prev_disposal == encoderinfo.get("disposal")
and prev_blend == encoderinfo.get("blend")
and "duration" in encoderinfo
):
previous["encoderinfo"]["duration"] += encoderinfo.get(
"duration", duration
)
previous["encoderinfo"]["duration"] += encoderinfo["duration"]
continue
else:
bbox = None
if "duration" not in encoderinfo:
encoderinfo["duration"] = duration
im_frames.append({"im": im_frame, "bbox": bbox, "encoderinfo": encoderinfo})
if len(im_frames) == 1 and not default_image:
@ -1208,7 +1207,7 @@ def _write_multiple_frames(im, fp, chunk, mode, rawmode, default_image, append_i
im_frame = im_frame.crop(bbox)
size = im_frame.size
encoderinfo = frame_data["encoderinfo"]
frame_duration = int(round(encoderinfo["duration"]))
frame_duration = int(round(encoderinfo.get("duration", 0)))
frame_disposal = encoderinfo.get("disposal", disposal)
frame_blend = encoderinfo.get("blend", blend)
# frame control