mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-11-11 04:07:21 +03:00
Merge pull request #5611 from radarhere/apng_info
This commit is contained in:
commit
d5d6c3ba8c
|
@ -441,6 +441,12 @@ def test_apng_save_duration_loop(tmp_path):
|
||||||
assert im.n_frames == 1
|
assert im.n_frames == 1
|
||||||
assert im.info.get("duration") == 750
|
assert im.info.get("duration") == 750
|
||||||
|
|
||||||
|
# test info duration
|
||||||
|
frame.info["duration"] = 750
|
||||||
|
frame.save(test_file, save_all=True)
|
||||||
|
with Image.open(test_file) as im:
|
||||||
|
assert im.info.get("duration") == 750
|
||||||
|
|
||||||
|
|
||||||
def test_apng_save_disposal(tmp_path):
|
def test_apng_save_disposal(tmp_path):
|
||||||
test_file = str(tmp_path / "temp.png")
|
test_file = str(tmp_path / "temp.png")
|
||||||
|
@ -531,6 +537,17 @@ def test_apng_save_disposal(tmp_path):
|
||||||
assert im.getpixel((0, 0)) == (0, 255, 0, 255)
|
assert im.getpixel((0, 0)) == (0, 255, 0, 255)
|
||||||
assert im.getpixel((64, 32)) == (0, 255, 0, 255)
|
assert im.getpixel((64, 32)) == (0, 255, 0, 255)
|
||||||
|
|
||||||
|
# test info disposal
|
||||||
|
red.info["disposal"] = PngImagePlugin.APNG_DISPOSE_OP_BACKGROUND
|
||||||
|
red.save(
|
||||||
|
test_file,
|
||||||
|
save_all=True,
|
||||||
|
append_images=[Image.new("RGBA", (10, 10), (0, 255, 0, 255))],
|
||||||
|
)
|
||||||
|
with Image.open(test_file) as im:
|
||||||
|
im.seek(1)
|
||||||
|
assert im.getpixel((64, 32)) == (0, 0, 0, 0)
|
||||||
|
|
||||||
|
|
||||||
def test_apng_save_disposal_previous(tmp_path):
|
def test_apng_save_disposal_previous(tmp_path):
|
||||||
test_file = str(tmp_path / "temp.png")
|
test_file = str(tmp_path / "temp.png")
|
||||||
|
@ -611,3 +628,10 @@ def test_apng_save_blend(tmp_path):
|
||||||
im.seek(2)
|
im.seek(2)
|
||||||
assert im.getpixel((0, 0)) == (0, 255, 0, 255)
|
assert im.getpixel((0, 0)) == (0, 255, 0, 255)
|
||||||
assert im.getpixel((64, 32)) == (0, 255, 0, 255)
|
assert im.getpixel((64, 32)) == (0, 255, 0, 255)
|
||||||
|
|
||||||
|
# test info blend
|
||||||
|
red.info["blend"] = PngImagePlugin.APNG_BLEND_OP_OVER
|
||||||
|
red.save(test_file, save_all=True, append_images=[green, transparent])
|
||||||
|
with Image.open(test_file) as im:
|
||||||
|
im.seek(2)
|
||||||
|
assert im.getpixel((0, 0)) == (0, 255, 0, 255)
|
||||||
|
|
|
@ -1061,8 +1061,10 @@ def _write_multiple_frames(im, fp, chunk, rawmode):
|
||||||
default_image = im.encoderinfo.get("default_image", im.info.get("default_image"))
|
default_image = im.encoderinfo.get("default_image", im.info.get("default_image"))
|
||||||
duration = im.encoderinfo.get("duration", im.info.get("duration", 0))
|
duration = im.encoderinfo.get("duration", im.info.get("duration", 0))
|
||||||
loop = im.encoderinfo.get("loop", im.info.get("loop", 0))
|
loop = im.encoderinfo.get("loop", im.info.get("loop", 0))
|
||||||
disposal = im.encoderinfo.get("disposal", im.info.get("disposal"))
|
disposal = im.encoderinfo.get(
|
||||||
blend = im.encoderinfo.get("blend", im.info.get("blend"))
|
"disposal", im.info.get("disposal", APNG_DISPOSE_OP_NONE)
|
||||||
|
)
|
||||||
|
blend = im.encoderinfo.get("blend", im.info.get("blend", APNG_BLEND_OP_SOURCE))
|
||||||
|
|
||||||
if default_image:
|
if default_image:
|
||||||
chain = itertools.chain(im.encoderinfo.get("append_images", []))
|
chain = itertools.chain(im.encoderinfo.get("append_images", []))
|
||||||
|
@ -1117,12 +1119,8 @@ def _write_multiple_frames(im, fp, chunk, rawmode):
|
||||||
and prev_disposal == encoderinfo.get("disposal")
|
and prev_disposal == encoderinfo.get("disposal")
|
||||||
and prev_blend == encoderinfo.get("blend")
|
and prev_blend == encoderinfo.get("blend")
|
||||||
):
|
):
|
||||||
frame_duration = encoderinfo.get("duration", 0)
|
if isinstance(duration, (list, tuple)):
|
||||||
if frame_duration:
|
previous["encoderinfo"]["duration"] += encoderinfo["duration"]
|
||||||
if "duration" in previous["encoderinfo"]:
|
|
||||||
previous["encoderinfo"]["duration"] += frame_duration
|
|
||||||
else:
|
|
||||||
previous["encoderinfo"]["duration"] = frame_duration
|
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
bbox = None
|
bbox = None
|
||||||
|
@ -1149,9 +1147,10 @@ def _write_multiple_frames(im, fp, chunk, rawmode):
|
||||||
bbox = frame_data["bbox"]
|
bbox = frame_data["bbox"]
|
||||||
im_frame = im_frame.crop(bbox)
|
im_frame = im_frame.crop(bbox)
|
||||||
size = im_frame.size
|
size = im_frame.size
|
||||||
duration = int(round(frame_data["encoderinfo"].get("duration", 0)))
|
encoderinfo = frame_data["encoderinfo"]
|
||||||
disposal = frame_data["encoderinfo"].get("disposal", APNG_DISPOSE_OP_NONE)
|
frame_duration = int(round(encoderinfo.get("duration", duration)))
|
||||||
blend = frame_data["encoderinfo"].get("blend", APNG_BLEND_OP_SOURCE)
|
frame_disposal = encoderinfo.get("disposal", disposal)
|
||||||
|
frame_blend = encoderinfo.get("blend", blend)
|
||||||
# frame control
|
# frame control
|
||||||
chunk(
|
chunk(
|
||||||
fp,
|
fp,
|
||||||
|
@ -1161,10 +1160,10 @@ def _write_multiple_frames(im, fp, chunk, rawmode):
|
||||||
o32(size[1]), # height
|
o32(size[1]), # height
|
||||||
o32(bbox[0]), # x_offset
|
o32(bbox[0]), # x_offset
|
||||||
o32(bbox[1]), # y_offset
|
o32(bbox[1]), # y_offset
|
||||||
o16(duration), # delay_numerator
|
o16(frame_duration), # delay_numerator
|
||||||
o16(1000), # delay_denominator
|
o16(1000), # delay_denominator
|
||||||
o8(disposal), # dispose_op
|
o8(frame_disposal), # dispose_op
|
||||||
o8(blend), # blend_op
|
o8(frame_blend), # blend_op
|
||||||
)
|
)
|
||||||
seq_num += 1
|
seq_num += 1
|
||||||
# frame data
|
# frame data
|
||||||
|
|
Loading…
Reference in New Issue
Block a user