From 8696f06fbe1b2a6b30fb5e64284bbb75055e5044 Mon Sep 17 00:00:00 2001 From: djy0 Date: Fri, 2 Aug 2019 08:47:38 +0800 Subject: [PATCH 1/8] Update test_file_gif.py --- Tests/test_file_gif.py | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/Tests/test_file_gif.py b/Tests/test_file_gif.py index 2ba370c3f..56cb9f5d5 100644 --- a/Tests/test_file_gif.py +++ b/Tests/test_file_gif.py @@ -472,7 +472,7 @@ class TestFileGif(PillowTestCase): except EOFError: pass - def test_identical_frames(self): + def test_partially_identical_frames(self): duration_list = [1000, 1500, 2000, 4000] out = self.tempfile("temp.gif") @@ -495,6 +495,37 @@ class TestFileGif(PillowTestCase): # Assert that the new duration is the total of the identical frames self.assertEqual(reread.info["duration"], 4500) + def test_totally_identical_frames(self): + duration_list = [1000, 1500, 2000, 4000] + + out = self.tempfile("temp.gif") + + image_path = "Tests/images/bc7-argb-8bpp_MipMaps-1.png" + im_list = [ + Image.open(image_path), + Image.open(image_path), + Image.open(image_path), + Image.open(image_path), + ] + mask = Image.new("RGBA", im_list[0].size, (255, 255, 255, 0)) + + frames = [] + for image in im_list: + frames.append(Image.alpha_composite(mask, image)) + + # duration as list + frames[0].save(out, + save_all=True, append_images=frames[1:], optimize=False, duration=duration_list, loop=0, + transparency=0) + + reread = Image.open(out) + + # Assert that the first three frames were combined + self.assertEqual(reread.n_frames, 1) + + # Assert that the new duration is the total of the identical frames + self.assertEqual(reread.info["duration"], 8500) + def test_number_of_loops(self): number_of_loops = 2 From fcaf27d51cfb9f92eb46a1194ae4ad75d1d65d5b Mon Sep 17 00:00:00 2001 From: djy0 Date: Fri, 2 Aug 2019 08:54:04 +0800 Subject: [PATCH 2/8] Update GifImagePlugin.py --- src/PIL/GifImagePlugin.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/PIL/GifImagePlugin.py b/src/PIL/GifImagePlugin.py index bbf6dc9d6..b5323d252 100644 --- a/src/PIL/GifImagePlugin.py +++ b/src/PIL/GifImagePlugin.py @@ -472,6 +472,10 @@ def _write_multiple_frames(im, fp, palette): else: bbox = None im_frames.append({"im": im_frame, "bbox": bbox, "encoderinfo": encoderinfo}) + + # see: https://github.com/python-pillow/Pillow/issues/4002 + if len(im_frames) == 1 and 'duration' in im_frames[0]['encoderinfo']: + im.encoderinfo['duration'] = im_frames[0]['encoderinfo']['duration'] if len(im_frames) > 1: for frame_data in im_frames: From 3c971bec4197b211ff95e5022a800ac50d982f8f Mon Sep 17 00:00:00 2001 From: djy0 Date: Fri, 2 Aug 2019 09:51:27 +0800 Subject: [PATCH 3/8] format --- Tests/test_file_gif.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Tests/test_file_gif.py b/Tests/test_file_gif.py index 56cb9f5d5..b90a73627 100644 --- a/Tests/test_file_gif.py +++ b/Tests/test_file_gif.py @@ -514,10 +514,16 @@ class TestFileGif(PillowTestCase): frames.append(Image.alpha_composite(mask, image)) # duration as list - frames[0].save(out, - save_all=True, append_images=frames[1:], optimize=False, duration=duration_list, loop=0, - transparency=0) - + frames[0].save( + out, + save_all=True, + append_images=frames[1:], + optimize=False, + duration=duration_list, + loop=0, + transparency=0, + ) + reread = Image.open(out) # Assert that the first three frames were combined From 3499f50e5220eb6dfe2498f26036b20a99e5070c Mon Sep 17 00:00:00 2001 From: djy0 Date: Fri, 2 Aug 2019 09:54:19 +0800 Subject: [PATCH 4/8] format --- src/PIL/GifImagePlugin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PIL/GifImagePlugin.py b/src/PIL/GifImagePlugin.py index b5323d252..b359f7259 100644 --- a/src/PIL/GifImagePlugin.py +++ b/src/PIL/GifImagePlugin.py @@ -474,8 +474,8 @@ def _write_multiple_frames(im, fp, palette): im_frames.append({"im": im_frame, "bbox": bbox, "encoderinfo": encoderinfo}) # see: https://github.com/python-pillow/Pillow/issues/4002 - if len(im_frames) == 1 and 'duration' in im_frames[0]['encoderinfo']: - im.encoderinfo['duration'] = im_frames[0]['encoderinfo']['duration'] + if len(im_frames) == 1 and "duration" in im_frames[0]["encoderinfo"]: + im.encoderinfo["duration"] = im_frames[0]["encoderinfo"]["duration"] if len(im_frames) > 1: for frame_data in im_frames: From 63c15dc3ba04c0cacd7a5414d3d2e6b8b9d84e73 Mon Sep 17 00:00:00 2001 From: djy0 Date: Fri, 2 Aug 2019 10:36:33 +0800 Subject: [PATCH 5/8] format --- Tests/test_file_gif.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Tests/test_file_gif.py b/Tests/test_file_gif.py index b90a73627..1704c76a5 100644 --- a/Tests/test_file_gif.py +++ b/Tests/test_file_gif.py @@ -523,7 +523,6 @@ class TestFileGif(PillowTestCase): loop=0, transparency=0, ) - reread = Image.open(out) # Assert that the first three frames were combined From dc9c0dbfbe286cbcb33c11a0c32af5c4d45e0131 Mon Sep 17 00:00:00 2001 From: djy0 Date: Fri, 2 Aug 2019 10:37:17 +0800 Subject: [PATCH 6/8] format --- src/PIL/GifImagePlugin.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/PIL/GifImagePlugin.py b/src/PIL/GifImagePlugin.py index b359f7259..d2f6cd1d3 100644 --- a/src/PIL/GifImagePlugin.py +++ b/src/PIL/GifImagePlugin.py @@ -472,7 +472,6 @@ def _write_multiple_frames(im, fp, palette): else: bbox = None im_frames.append({"im": im_frame, "bbox": bbox, "encoderinfo": encoderinfo}) - # see: https://github.com/python-pillow/Pillow/issues/4002 if len(im_frames) == 1 and "duration" in im_frames[0]["encoderinfo"]: im.encoderinfo["duration"] = im_frames[0]["encoderinfo"]["duration"] From 0872cb43777606ddd55cd9803694469ebb21e843 Mon Sep 17 00:00:00 2001 From: djy0 Date: Sun, 4 Aug 2019 17:32:02 +0800 Subject: [PATCH 7/8] fix comment --- Tests/test_file_gif.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/test_file_gif.py b/Tests/test_file_gif.py index 1704c76a5..a4d021f58 100644 --- a/Tests/test_file_gif.py +++ b/Tests/test_file_gif.py @@ -525,7 +525,7 @@ class TestFileGif(PillowTestCase): ) reread = Image.open(out) - # Assert that the first three frames were combined + # Assert that all four frames were combined self.assertEqual(reread.n_frames, 1) # Assert that the new duration is the total of the identical frames From 2dbfabe6d5e553e9bf6510f8d2439bc90757309e Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Sat, 24 Aug 2019 08:10:45 +1000 Subject: [PATCH 8/8] Simplifications --- Tests/test_file_gif.py | 50 +++++++++++++-------------------------- src/PIL/GifImagePlugin.py | 8 ++++--- 2 files changed, 22 insertions(+), 36 deletions(-) diff --git a/Tests/test_file_gif.py b/Tests/test_file_gif.py index a4d021f58..4ff9727e1 100644 --- a/Tests/test_file_gif.py +++ b/Tests/test_file_gif.py @@ -472,7 +472,7 @@ class TestFileGif(PillowTestCase): except EOFError: pass - def test_partially_identical_frames(self): + def test_identical_frames(self): duration_list = [1000, 1500, 2000, 4000] out = self.tempfile("temp.gif") @@ -495,41 +495,25 @@ class TestFileGif(PillowTestCase): # Assert that the new duration is the total of the identical frames self.assertEqual(reread.info["duration"], 4500) - def test_totally_identical_frames(self): - duration_list = [1000, 1500, 2000, 4000] + def test_identical_frames_to_single_frame(self): + for duration in ([1000, 1500, 2000, 4000], (1000, 1500, 2000, 4000), 8500): + out = self.tempfile("temp.gif") + im_list = [ + Image.new("L", (100, 100), "#000"), + Image.new("L", (100, 100), "#000"), + Image.new("L", (100, 100), "#000"), + ] - out = self.tempfile("temp.gif") + im_list[0].save( + out, save_all=True, append_images=im_list[1:], duration=duration + ) + reread = Image.open(out) - image_path = "Tests/images/bc7-argb-8bpp_MipMaps-1.png" - im_list = [ - Image.open(image_path), - Image.open(image_path), - Image.open(image_path), - Image.open(image_path), - ] - mask = Image.new("RGBA", im_list[0].size, (255, 255, 255, 0)) + # Assert that all frames were combined + self.assertEqual(reread.n_frames, 1) - frames = [] - for image in im_list: - frames.append(Image.alpha_composite(mask, image)) - - # duration as list - frames[0].save( - out, - save_all=True, - append_images=frames[1:], - optimize=False, - duration=duration_list, - loop=0, - transparency=0, - ) - reread = Image.open(out) - - # Assert that all four frames were combined - self.assertEqual(reread.n_frames, 1) - - # Assert that the new duration is the total of the identical frames - self.assertEqual(reread.info["duration"], 8500) + # Assert that the new duration is the total of the identical frames + self.assertEqual(reread.info["duration"], 8500) def test_number_of_loops(self): number_of_loops = 2 diff --git a/src/PIL/GifImagePlugin.py b/src/PIL/GifImagePlugin.py index d2f6cd1d3..07f5ab683 100644 --- a/src/PIL/GifImagePlugin.py +++ b/src/PIL/GifImagePlugin.py @@ -472,9 +472,6 @@ def _write_multiple_frames(im, fp, palette): else: bbox = None im_frames.append({"im": im_frame, "bbox": bbox, "encoderinfo": encoderinfo}) - # see: https://github.com/python-pillow/Pillow/issues/4002 - if len(im_frames) == 1 and "duration" in im_frames[0]["encoderinfo"]: - im.encoderinfo["duration"] = im_frames[0]["encoderinfo"]["duration"] if len(im_frames) > 1: for frame_data in im_frames: @@ -492,6 +489,11 @@ def _write_multiple_frames(im, fp, palette): 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"]) def _save_all(im, fp, filename):