From 4b2746fc39afe17abcaf2096250e61bf784d631c Mon Sep 17 00:00:00 2001 From: Riley Lahd Date: Fri, 22 Mar 2019 08:19:01 -0600 Subject: [PATCH] Remove disposal 2 duplicate frame exemption and add true delta test --- Tests/test_file_gif.py | 63 ++++++++++++++++++++++++++++++++++----- src/PIL/GifImagePlugin.py | 3 +- 2 files changed, 56 insertions(+), 10 deletions(-) diff --git a/Tests/test_file_gif.py b/Tests/test_file_gif.py index 21a22630e..c754d6ed5 100644 --- a/Tests/test_file_gif.py +++ b/Tests/test_file_gif.py @@ -315,19 +315,19 @@ class TestFileGif(PillowTestCase): img.seek(img.tell() + 1) self.assertEqual(img.disposal_method, i+1) - def test_dispose2_diff(self): + def test_dispose2_palette(self): out = self.tempfile('temp.gif') # 4 backgrounds: White, Grey, Black, Red - backgrounds = [(255, 255, 255), (153, 153, 153), (0, 0, 0), (255, 0, 0)] + circles = [(255, 255, 255), (153, 153, 153), (0, 0, 0), (255, 0, 0)] im_list = [] - for background in backgrounds: - img = Image.new('RGB', (100, 100), background) + for circle in circles: + img = Image.new('RGB', (100, 100), (255,0,0)) # Red circle in center of each frame d = ImageDraw.Draw(img) - d.ellipse([(40, 40), (60, 60)], fill='#f00') + d.ellipse([(40, 40), (60, 60)], fill=circle) im_list.append(img) @@ -340,15 +340,62 @@ class TestFileGif(PillowTestCase): img = Image.open(out) - for i, background in enumerate(backgrounds): + for i, circle in enumerate(circles): img.seek(i) rgb_img = img.convert('RGB') # Check top left pixel matches background - self.assertEqual(rgb_img.getpixel((0, 0)), background) + self.assertEqual(rgb_img.getpixel((0, 0)), (255, 0, 0)) # Center remains red every frame - self.assertEqual(rgb_img.getpixel((50, 50)), (255, 0, 0)) + self.assertEqual(rgb_img.getpixel((50, 50)), circle) + + def test_dispose2_diff(self): + out = self.tempfile('temp.gif') + + # 4 frames: red/blue, red/red, blue/blue, red/blue + circles = [ + ((255, 0, 0, 255),(0, 0, 255, 255)), + ((255, 0, 0, 255),(255, 0, 0, 255)), + ((0, 0, 255, 255),(0, 0, 255, 255)), + ((255, 0, 0, 255),(0, 0, 255, 255)) + ] + + im_list = [] + for i in range(len(circles)): + # Transparent BG + img = Image.new('RGBA', (100, 100), (255,255,255,0)) + + # Two circles per frame + d = ImageDraw.Draw(img) + d.ellipse([(0, 30), (40, 70)], fill=circles[i][0]) + d.ellipse([(60, 30), (100, 70)], fill=circles[i][1]) + + im_list.append(img) + + im_list[0].save( + out, + save_all=True, + append_images=im_list[1:], + disposal=2, + transparency=0 + ) + + img = Image.open(out) + + for i, colours in enumerate(circles): + img.seek(i) + rgb_img = img.convert('RGBA') + + # Check left circle is correct colour + self.assertEqual(rgb_img.getpixel((20, 50)), colours[0]) + + # Check right circle is correct colour + self.assertEqual(rgb_img.getpixel((80, 50)), colours[1]) + + # Check BG is correct colour + self.assertEqual(rgb_img.getpixel((1, 1)), (255,255,255,0)) + def test_iss634(self): img = Image.open("Tests/images/iss634.gif") diff --git a/src/PIL/GifImagePlugin.py b/src/PIL/GifImagePlugin.py index 49417c303..64ef63b2e 100644 --- a/src/PIL/GifImagePlugin.py +++ b/src/PIL/GifImagePlugin.py @@ -457,8 +457,7 @@ def _write_multiple_frames(im, fp, palette): delta = ImageChops.subtract_modulo( im_frame.convert('RGB'), base_image.convert('RGB')) bbox = delta.getbbox() - if not bbox and not ("disposal" in encoderinfo - and encoderinfo["disposal"] == 2): + if not bbox: # This frame is identical to the previous frame if duration: previous['encoderinfo']['duration'] += \