Use context manager for APNG tests

This commit is contained in:
Peter Rowlands 2020-01-10 14:44:47 +09:00 committed by Andrew Murray
parent 0f84fa7707
commit d05b73cd08

View File

@ -11,14 +11,14 @@ class TestFilePng(PillowTestCase):
# https://philip.html5.org/tests/apng/tests.html # https://philip.html5.org/tests/apng/tests.html
# (referenced from https://wiki.mozilla.org/APNG_Specification) # (referenced from https://wiki.mozilla.org/APNG_Specification)
def test_apng_basic(self): def test_apng_basic(self):
im = Image.open("Tests/images/apng/single_frame.png") with Image.open("Tests/images/apng/single_frame.png") as im:
self.assertTrue(im.is_animated) self.assertTrue(im.is_animated)
self.assertEqual(im.get_format_mimetype(), "image/apng") self.assertEqual(im.get_format_mimetype(), "image/apng")
self.assertIsNone(im.info.get("default_image")) self.assertIsNone(im.info.get("default_image"))
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255))
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255))
im = Image.open("Tests/images/apng/single_frame_default.png") with Image.open("Tests/images/apng/single_frame_default.png") as im:
self.assertTrue(im.is_animated) self.assertTrue(im.is_animated)
self.assertEqual(im.get_format_mimetype(), "image/apng") self.assertEqual(im.get_format_mimetype(), "image/apng")
self.assertTrue(im.info.get("default_image")) self.assertTrue(im.info.get("default_image"))
@ -41,102 +41,104 @@ class TestFilePng(PillowTestCase):
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255))
def test_apng_fdat(self): def test_apng_fdat(self):
im = Image.open("Tests/images/apng/split_fdat.png") with Image.open("Tests/images/apng/split_fdat.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255))
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255))
im = Image.open("Tests/images/apng/split_fdat_zero_chunk.png") with Image.open("Tests/images/apng/split_fdat_zero_chunk.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255))
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255))
def test_apng_dispose(self): def test_apng_dispose(self):
im = Image.open("Tests/images/apng/dispose_op_none.png") with Image.open("Tests/images/apng/dispose_op_none.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255))
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255))
im = Image.open("Tests/images/apng/dispose_op_background.png") with Image.open("Tests/images/apng/dispose_op_background.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 0, 0, 0)) self.assertEqual(im.getpixel((0, 0)), (0, 0, 0, 0))
self.assertEqual(im.getpixel((64, 32)), (0, 0, 0, 0)) self.assertEqual(im.getpixel((64, 32)), (0, 0, 0, 0))
im = Image.open("Tests/images/apng/dispose_op_background_final.png") with Image.open("Tests/images/apng/dispose_op_background_final.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255))
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255))
im = Image.open("Tests/images/apng/dispose_op_previous.png") with Image.open("Tests/images/apng/dispose_op_previous.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255))
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255))
im = Image.open("Tests/images/apng/dispose_op_previous_final.png") with Image.open("Tests/images/apng/dispose_op_previous_final.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255))
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255))
im = Image.open("Tests/images/apng/dispose_op_previous_first.png") with Image.open("Tests/images/apng/dispose_op_previous_first.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 0, 0, 0)) self.assertEqual(im.getpixel((0, 0)), (0, 0, 0, 0))
self.assertEqual(im.getpixel((64, 32)), (0, 0, 0, 0)) self.assertEqual(im.getpixel((64, 32)), (0, 0, 0, 0))
def test_apng_dispose_region(self): def test_apng_dispose_region(self):
im = Image.open("Tests/images/apng/dispose_op_none_region.png") with Image.open("Tests/images/apng/dispose_op_none_region.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255))
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255))
im = Image.open("Tests/images/apng/dispose_op_background_before_region.png") with Image.open(
"Tests/images/apng/dispose_op_background_before_region.png"
) as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 0, 0, 0)) self.assertEqual(im.getpixel((0, 0)), (0, 0, 0, 0))
self.assertEqual(im.getpixel((64, 32)), (0, 0, 0, 0)) self.assertEqual(im.getpixel((64, 32)), (0, 0, 0, 0))
im = Image.open("Tests/images/apng/dispose_op_background_region.png") with Image.open("Tests/images/apng/dispose_op_background_region.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 0, 255, 255)) self.assertEqual(im.getpixel((0, 0)), (0, 0, 255, 255))
self.assertEqual(im.getpixel((64, 32)), (0, 0, 0, 0)) self.assertEqual(im.getpixel((64, 32)), (0, 0, 0, 0))
im = Image.open("Tests/images/apng/dispose_op_previous_region.png") with Image.open("Tests/images/apng/dispose_op_previous_region.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255))
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255))
def test_apng_blend(self): def test_apng_blend(self):
im = Image.open("Tests/images/apng/blend_op_source_solid.png") with Image.open("Tests/images/apng/blend_op_source_solid.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255))
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255))
im = Image.open("Tests/images/apng/blend_op_source_transparent.png") with Image.open("Tests/images/apng/blend_op_source_transparent.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 0, 0, 0)) self.assertEqual(im.getpixel((0, 0)), (0, 0, 0, 0))
self.assertEqual(im.getpixel((64, 32)), (0, 0, 0, 0)) self.assertEqual(im.getpixel((64, 32)), (0, 0, 0, 0))
im = Image.open("Tests/images/apng/blend_op_source_near_transparent.png") with Image.open("Tests/images/apng/blend_op_source_near_transparent.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 2)) self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 2))
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 2)) self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 2))
im = Image.open("Tests/images/apng/blend_op_over.png") with Image.open("Tests/images/apng/blend_op_over.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255))
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255))
im = Image.open("Tests/images/apng/blend_op_over_near_transparent.png") with Image.open("Tests/images/apng/blend_op_over_near_transparent.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 97)) self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 97))
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255))
def test_apng_chunk_order(self): def test_apng_chunk_order(self):
im = Image.open("Tests/images/apng/fctl_actl.png") with Image.open("Tests/images/apng/fctl_actl.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255))
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255))
def test_apng_delay(self): def test_apng_delay(self):
im = Image.open("Tests/images/apng/delay.png") with Image.open("Tests/images/apng/delay.png") as im:
im.seek(1) im.seek(1)
self.assertEqual(im.info.get("duration"), 500.0) self.assertEqual(im.info.get("duration"), 500.0)
im.seek(2) im.seek(2)
@ -146,25 +148,25 @@ class TestFilePng(PillowTestCase):
im.seek(4) im.seek(4)
self.assertEqual(im.info.get("duration"), 1000.0) self.assertEqual(im.info.get("duration"), 1000.0)
im = Image.open("Tests/images/apng/delay_round.png") with Image.open("Tests/images/apng/delay_round.png") as im:
im.seek(1) im.seek(1)
self.assertEqual(im.info.get("duration"), 500.0) self.assertEqual(im.info.get("duration"), 500.0)
im.seek(2) im.seek(2)
self.assertEqual(im.info.get("duration"), 1000.0) self.assertEqual(im.info.get("duration"), 1000.0)
im = Image.open("Tests/images/apng/delay_short_max.png") with Image.open("Tests/images/apng/delay_short_max.png") as im:
im.seek(1) im.seek(1)
self.assertEqual(im.info.get("duration"), 500.0) self.assertEqual(im.info.get("duration"), 500.0)
im.seek(2) im.seek(2)
self.assertEqual(im.info.get("duration"), 1000.0) self.assertEqual(im.info.get("duration"), 1000.0)
im = Image.open("Tests/images/apng/delay_zero_denom.png") with Image.open("Tests/images/apng/delay_zero_denom.png") as im:
im.seek(1) im.seek(1)
self.assertEqual(im.info.get("duration"), 500.0) self.assertEqual(im.info.get("duration"), 500.0)
im.seek(2) im.seek(2)
self.assertEqual(im.info.get("duration"), 1000.0) self.assertEqual(im.info.get("duration"), 1000.0)
im = Image.open("Tests/images/apng/delay_zero_numer.png") with Image.open("Tests/images/apng/delay_zero_numer.png") as im:
im.seek(1) im.seek(1)
self.assertEqual(im.info.get("duration"), 0.0) self.assertEqual(im.info.get("duration"), 0.0)
im.seek(2) im.seek(2)
@ -175,46 +177,46 @@ class TestFilePng(PillowTestCase):
self.assertEqual(im.info.get("duration"), 1000.0) self.assertEqual(im.info.get("duration"), 1000.0)
def test_apng_num_plays(self): def test_apng_num_plays(self):
im = Image.open("Tests/images/apng/num_plays.png") with Image.open("Tests/images/apng/num_plays.png") as im:
self.assertEqual(im.info.get("loop"), 0) self.assertEqual(im.info.get("loop"), 0)
im = Image.open("Tests/images/apng/num_plays_1.png") with Image.open("Tests/images/apng/num_plays_1.png") as im:
self.assertEqual(im.info.get("loop"), 1) self.assertEqual(im.info.get("loop"), 1)
def test_apng_mode(self): def test_apng_mode(self):
im = Image.open("Tests/images/apng/mode_16bit.png") with Image.open("Tests/images/apng/mode_16bit.png") as im:
self.assertEqual(im.mode, "RGBA") self.assertEqual(im.mode, "RGBA")
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (0, 0, 128, 191)) self.assertEqual(im.getpixel((0, 0)), (0, 0, 128, 191))
self.assertEqual(im.getpixel((64, 32)), (0, 0, 128, 191)) self.assertEqual(im.getpixel((64, 32)), (0, 0, 128, 191))
im = Image.open("Tests/images/apng/mode_greyscale.png") with Image.open("Tests/images/apng/mode_greyscale.png") as im:
self.assertEqual(im.mode, "L") self.assertEqual(im.mode, "L")
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), 128) self.assertEqual(im.getpixel((0, 0)), 128)
self.assertEqual(im.getpixel((64, 32)), 255) self.assertEqual(im.getpixel((64, 32)), 255)
im = Image.open("Tests/images/apng/mode_greyscale_alpha.png") with Image.open("Tests/images/apng/mode_greyscale_alpha.png") as im:
self.assertEqual(im.mode, "LA") self.assertEqual(im.mode, "LA")
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
self.assertEqual(im.getpixel((0, 0)), (128, 191)) self.assertEqual(im.getpixel((0, 0)), (128, 191))
self.assertEqual(im.getpixel((64, 32)), (128, 191)) self.assertEqual(im.getpixel((64, 32)), (128, 191))
im = Image.open("Tests/images/apng/mode_palette.png") with Image.open("Tests/images/apng/mode_palette.png") as im:
self.assertEqual(im.mode, "P") self.assertEqual(im.mode, "P")
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
im = im.convert("RGB") im = im.convert("RGB")
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0)) self.assertEqual(im.getpixel((0, 0)), (0, 255, 0))
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0)) self.assertEqual(im.getpixel((64, 32)), (0, 255, 0))
im = Image.open("Tests/images/apng/mode_palette_alpha.png") with Image.open("Tests/images/apng/mode_palette_alpha.png") as im:
self.assertEqual(im.mode, "P") self.assertEqual(im.mode, "P")
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
im = im.convert("RGBA") im = im.convert("RGBA")
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255))
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255))
im = Image.open("Tests/images/apng/mode_palette_1bit_alpha.png") with Image.open("Tests/images/apng/mode_palette_1bit_alpha.png") as im:
self.assertEqual(im.mode, "P") self.assertEqual(im.mode, "P")
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
im = im.convert("RGBA") im = im.convert("RGBA")
@ -222,50 +224,52 @@ class TestFilePng(PillowTestCase):
self.assertEqual(im.getpixel((64, 32)), (0, 0, 255, 128)) self.assertEqual(im.getpixel((64, 32)), (0, 0, 255, 128))
def test_apng_chunk_errors(self): def test_apng_chunk_errors(self):
im = Image.open("Tests/images/apng/chunk_no_actl.png") with Image.open("Tests/images/apng/chunk_no_actl.png") as im:
self.assertFalse(im.is_animated) self.assertFalse(im.is_animated)
def open(): def open():
im = Image.open("Tests/images/apng/chunk_multi_actl.png") with Image.open("Tests/images/apng/chunk_multi_actl.png") as im:
im.load() im.load()
self.assertFalse(im.is_animated)
pytest.warns(UserWarning, open) pytest.warns(UserWarning, open)
with Image.open("Tests/images/apng/chunk_actl_after_idat.png") as im:
self.assertFalse(im.is_animated) self.assertFalse(im.is_animated)
im = Image.open("Tests/images/apng/chunk_actl_after_idat.png") with Image.open("Tests/images/apng/chunk_no_fctl.png") as im:
self.assertFalse(im.is_animated)
im = Image.open("Tests/images/apng/chunk_no_fctl.png")
with self.assertRaises(SyntaxError): with self.assertRaises(SyntaxError):
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
im = Image.open("Tests/images/apng/chunk_repeat_fctl.png") with Image.open("Tests/images/apng/chunk_repeat_fctl.png") as im:
with self.assertRaises(SyntaxError): with self.assertRaises(SyntaxError):
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
im = Image.open("Tests/images/apng/chunk_no_fdat.png") with Image.open("Tests/images/apng/chunk_no_fdat.png") as im:
with self.assertRaises(SyntaxError): with self.assertRaises(SyntaxError):
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
def test_apng_syntax_errors(self): def test_apng_syntax_errors(self):
def open(): def open_frames_zero():
im = Image.open("Tests/images/apng/syntax_num_frames_zero.png") with Image.open("Tests/images/apng/syntax_num_frames_zero.png") as im:
self.assertFalse(im.is_animated) self.assertFalse(im.is_animated)
with self.assertRaises(OSError): with self.assertRaises(OSError):
im.load() im.load()
pytest.warns(UserWarning, open) pytest.warns(UserWarning, open_frames_zero)
def open(): def open_frames_zero_default():
im = Image.open("Tests/images/apng/syntax_num_frames_zero_default.png") with Image.open(
"Tests/images/apng/syntax_num_frames_zero_default.png"
) as im:
self.assertFalse(im.is_animated) self.assertFalse(im.is_animated)
im.load() im.load()
pytest.warns(UserWarning, open) pytest.warns(UserWarning, open_frames_zero_default)
# we can handle this case gracefully # we can handle this case gracefully
exception = None exception = None
im = Image.open("Tests/images/apng/syntax_num_frames_low.png") with Image.open("Tests/images/apng/syntax_num_frames_low.png") as im:
try: try:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
except Exception as e: except Exception as e:
@ -273,12 +277,12 @@ class TestFilePng(PillowTestCase):
self.assertIsNone(exception) self.assertIsNone(exception)
with self.assertRaises(SyntaxError): with self.assertRaises(SyntaxError):
im = Image.open("Tests/images/apng/syntax_num_frames_high.png") with Image.open("Tests/images/apng/syntax_num_frames_high.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
im.load() im.load()
def open(): def open():
im = Image.open("Tests/images/apng/syntax_num_frames_invalid.png") with Image.open("Tests/images/apng/syntax_num_frames_invalid.png") as im:
self.assertFalse(im.is_animated) self.assertFalse(im.is_animated)
im.load() im.load()
@ -296,12 +300,12 @@ class TestFilePng(PillowTestCase):
] ]
for f in test_files: for f in test_files:
with self.assertRaises(SyntaxError): with self.assertRaises(SyntaxError):
im = Image.open("Tests/images/apng/{0}".format(f)) with Image.open("Tests/images/apng/{0}".format(f)) as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
im.load() im.load()
def test_apng_save(self): def test_apng_save(self):
im = Image.open("Tests/images/apng/single_frame.png") with Image.open("Tests/images/apng/single_frame.png") as im:
test_file = self.tempfile("temp.png") test_file = self.tempfile("temp.png")
im.save(test_file, save_all=True) im.save(test_file, save_all=True)
@ -313,10 +317,10 @@ class TestFilePng(PillowTestCase):
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255)) self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255))
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255)) self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255))
im = Image.open("Tests/images/apng/single_frame_default.png") with Image.open("Tests/images/apng/single_frame_default.png") as im:
frames = [] frames = []
for im in ImageSequence.Iterator(im): for frame_im in ImageSequence.Iterator(im):
frames.append(im.copy()) frames.append(frame_im.copy())
frames[0].save( frames[0].save(
test_file, save_all=True, default_image=True, append_images=frames[1:] test_file, save_all=True, default_image=True, append_images=frames[1:]
) )
@ -352,15 +356,15 @@ class TestFilePng(PillowTestCase):
def test_apng_save_duration_loop(self): def test_apng_save_duration_loop(self):
test_file = self.tempfile("temp.png") test_file = self.tempfile("temp.png")
im = Image.open("Tests/images/apng/delay.png") with Image.open("Tests/images/apng/delay.png") as im:
frames = [] frames = []
durations = [] durations = []
loop = im.info.get("loop") loop = im.info.get("loop")
default_image = im.info.get("default_image") default_image = im.info.get("default_image")
for i, im in enumerate(ImageSequence.Iterator(im)): for i, frame_im in enumerate(ImageSequence.Iterator(im)):
frames.append(im.copy()) frames.append(frame_im.copy())
if i != 0 or not default_image: if i != 0 or not default_image:
durations.append(im.info.get("duration", 0)) durations.append(frame_im.info.get("duration", 0))
frames[0].save( frames[0].save(
test_file, test_file,
save_all=True, save_all=True,
@ -369,6 +373,7 @@ class TestFilePng(PillowTestCase):
duration=durations, duration=durations,
loop=loop, loop=loop,
) )
with Image.open(test_file) as im: with Image.open(test_file) as im:
im.load() im.load()
self.assertEqual(im.info.get("loop"), loop) self.assertEqual(im.info.get("loop"), loop)