Skip to content

Commit 3f111b9

Browse files
authored
Merge pull request #8748 from radarhere/gif
2 parents 1ac527a + 8f4bfe1 commit 3f111b9

File tree

2 files changed

+32
-11
lines changed

2 files changed

+32
-11
lines changed

Tests/test_file_gif.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,21 @@ def test_dispose2_previous_frame(tmp_path: Path) -> None:
759759
assert im.getpixel((0, 0)) == (0, 0, 0, 255)
760760

761761

762+
def test_dispose2_without_transparency(tmp_path: Path) -> None:
763+
out = str(tmp_path / "temp.gif")
764+
765+
im = Image.new("P", (100, 100))
766+
767+
im2 = Image.new("P", (100, 100), (0, 0, 0))
768+
im2.putpixel((50, 50), (255, 0, 0))
769+
770+
im.save(out, save_all=True, append_images=[im2], disposal=2)
771+
772+
with Image.open(out) as reloaded:
773+
reloaded.seek(1)
774+
assert reloaded.tile[0].extents == (0, 0, 100, 100)
775+
776+
762777
def test_transparency_in_second_frame(tmp_path: Path) -> None:
763778
out = str(tmp_path / "temp.gif")
764779
with Image.open("Tests/images/different_transparency.gif") as im:

src/PIL/GifImagePlugin.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -689,16 +689,21 @@ def _write_multiple_frames(
689689
im_frames[-1].encoderinfo["duration"] += encoderinfo["duration"]
690690
continue
691691
if im_frames[-1].encoderinfo.get("disposal") == 2:
692-
if background_im is None:
693-
color = im.encoderinfo.get(
694-
"transparency", im.info.get("transparency", (0, 0, 0))
695-
)
696-
background = _get_background(im_frame, color)
697-
background_im = Image.new("P", im_frame.size, background)
698-
first_palette = im_frames[0].im.palette
699-
assert first_palette is not None
700-
background_im.putpalette(first_palette, first_palette.mode)
701-
bbox = _getbbox(background_im, im_frame)[1]
692+
# To appear correctly in viewers using a convention,
693+
# only consider transparency, and not background color
694+
color = im.encoderinfo.get(
695+
"transparency", im.info.get("transparency")
696+
)
697+
if color is not None:
698+
if background_im is None:
699+
background = _get_background(im_frame, color)
700+
background_im = Image.new("P", im_frame.size, background)
701+
first_palette = im_frames[0].im.palette
702+
assert first_palette is not None
703+
background_im.putpalette(first_palette, first_palette.mode)
704+
bbox = _getbbox(background_im, im_frame)[1]
705+
else:
706+
bbox = (0, 0) + im_frame.size
702707
elif encoderinfo.get("optimize") and im_frame.mode != "1":
703708
if "transparency" not in encoderinfo:
704709
assert im_frame.palette is not None
@@ -764,7 +769,8 @@ def _write_multiple_frames(
764769
if not palette:
765770
frame_data.encoderinfo["include_color_table"] = True
766771

767-
im_frame = im_frame.crop(frame_data.bbox)
772+
if frame_data.bbox != (0, 0) + im_frame.size:
773+
im_frame = im_frame.crop(frame_data.bbox)
768774
offset = frame_data.bbox[:2]
769775
_write_frame_data(fp, im_frame, offset, frame_data.encoderinfo)
770776
return True

0 commit comments

Comments
 (0)