diff --git a/Tests/images/first_frame_transparency.gif b/Tests/images/first_frame_transparency.gif new file mode 100644 index 000000000..86dc0de64 Binary files /dev/null and b/Tests/images/first_frame_transparency.gif differ diff --git a/Tests/images/transparent_dispose.gif b/Tests/images/transparent_dispose.gif new file mode 100644 index 000000000..92b615543 Binary files /dev/null and b/Tests/images/transparent_dispose.gif differ diff --git a/Tests/test_file_gif.py b/Tests/test_file_gif.py index df029dceb..2b577b36f 100644 --- a/Tests/test_file_gif.py +++ b/Tests/test_file_gif.py @@ -298,6 +298,12 @@ def test_eoferror(): im.seek(n_frames - 1) +def test_first_frame_transparency(): + with Image.open("Tests/images/first_frame_transparency.gif") as im: + px = im.load() + assert px[0, 0] == im.info["transparency"] + + def test_dispose_none(): with Image.open("Tests/images/dispose_none.gif") as img: try: @@ -331,6 +337,16 @@ def test_dispose_background(): pass +def test_transparent_dispose(): + expected_colors = [(2, 1, 2), (0, 1, 0), (2, 1, 2)] + with Image.open("Tests/images/transparent_dispose.gif") as img: + for frame in range(3): + img.seek(frame) + for x in range(3): + color = img.getpixel((x, 0)) + assert color == expected_colors[frame][x] + + def test_dispose_previous(): with Image.open("Tests/images/dispose_prev.gif") as img: try: diff --git a/src/PIL/GifImagePlugin.py b/src/PIL/GifImagePlugin.py index 5c93de2c9..2f988ff43 100644 --- a/src/PIL/GifImagePlugin.py +++ b/src/PIL/GifImagePlugin.py @@ -269,9 +269,14 @@ class GifImageFile(ImageFile.ImageFile): dispose_size = (x1 - x0, y1 - y0) Image._decompression_bomb_check(dispose_size) - self.dispose = Image.core.fill( - "P", dispose_size, self.info.get("background", 0) + + # by convention, attempt to use transparency first + color = ( + frame_transparency + if frame_transparency is not None + else self.info.get("background", 0) ) + self.dispose = Image.core.fill("P", dispose_size, color) else: # replace with previous contents if self.im: @@ -317,6 +322,12 @@ class GifImageFile(ImageFile.ImageFile): if self.palette: self.mode = "P" + def load_prepare(self): + if not self.im and "transparency" in self.info: + self.im = Image.core.fill(self.mode, self.size, self.info["transparency"]) + + super(GifImageFile, self).load_prepare() + def tell(self): return self.__frame