mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-11-11 04:07:21 +03:00
Merge pull request #6787 from radarhere/gif_disposal
Resolves https://github.com/python-pillow/Pillow/issues/6785
This commit is contained in:
commit
7a19251d0d
|
@ -677,6 +677,24 @@ def test_dispose2_background(tmp_path):
|
|||
assert im.getpixel((0, 0)) == (255, 0, 0)
|
||||
|
||||
|
||||
def test_dispose2_background_frame(tmp_path):
|
||||
out = str(tmp_path / "temp.gif")
|
||||
|
||||
im_list = [Image.new("RGBA", (1, 20))]
|
||||
|
||||
different_frame = Image.new("RGBA", (1, 20))
|
||||
different_frame.putpixel((0, 10), (255, 0, 0, 255))
|
||||
im_list.append(different_frame)
|
||||
|
||||
# Frame that matches the background
|
||||
im_list.append(Image.new("RGBA", (1, 20)))
|
||||
|
||||
im_list[0].save(out, save_all=True, append_images=im_list[1:], disposal=2)
|
||||
|
||||
with Image.open(out) as im:
|
||||
assert im.n_frames == 3
|
||||
|
||||
|
||||
def test_transparency_in_second_frame(tmp_path):
|
||||
out = str(tmp_path / "temp.gif")
|
||||
with Image.open("Tests/images/different_transparency.gif") as im:
|
||||
|
|
|
@ -565,6 +565,16 @@ def _write_single_frame(im, fp, palette):
|
|||
fp.write(b"\0") # end of image data
|
||||
|
||||
|
||||
def _getbbox(base_im, im_frame):
|
||||
if _get_palette_bytes(im_frame) == _get_palette_bytes(base_im):
|
||||
delta = ImageChops.subtract_modulo(im_frame, base_im)
|
||||
else:
|
||||
delta = ImageChops.subtract_modulo(
|
||||
im_frame.convert("RGB"), base_im.convert("RGB")
|
||||
)
|
||||
return delta.getbbox()
|
||||
|
||||
|
||||
def _write_multiple_frames(im, fp, palette):
|
||||
|
||||
duration = im.encoderinfo.get("duration")
|
||||
|
@ -598,6 +608,12 @@ def _write_multiple_frames(im, fp, palette):
|
|||
if im_frames:
|
||||
# delta frame
|
||||
previous = im_frames[-1]
|
||||
bbox = _getbbox(previous["im"], im_frame)
|
||||
if not bbox:
|
||||
# This frame is identical to the previous frame
|
||||
if encoderinfo.get("duration"):
|
||||
previous["encoderinfo"]["duration"] += encoderinfo["duration"]
|
||||
continue
|
||||
if encoderinfo.get("disposal") == 2:
|
||||
if background_im is None:
|
||||
color = im.encoderinfo.get(
|
||||
|
@ -606,21 +622,7 @@ def _write_multiple_frames(im, fp, palette):
|
|||
background = _get_background(im_frame, color)
|
||||
background_im = Image.new("P", im_frame.size, background)
|
||||
background_im.putpalette(im_frames[0]["im"].palette)
|
||||
base_im = background_im
|
||||
else:
|
||||
base_im = previous["im"]
|
||||
if _get_palette_bytes(im_frame) == _get_palette_bytes(base_im):
|
||||
delta = ImageChops.subtract_modulo(im_frame, base_im)
|
||||
else:
|
||||
delta = ImageChops.subtract_modulo(
|
||||
im_frame.convert("RGB"), base_im.convert("RGB")
|
||||
)
|
||||
bbox = delta.getbbox()
|
||||
if not bbox:
|
||||
# This frame is identical to the previous frame
|
||||
if encoderinfo.get("duration"):
|
||||
previous["encoderinfo"]["duration"] += encoderinfo["duration"]
|
||||
continue
|
||||
bbox = _getbbox(background_im, im_frame)
|
||||
else:
|
||||
bbox = None
|
||||
im_frames.append({"im": im_frame, "bbox": bbox, "encoderinfo": encoderinfo})
|
||||
|
|
Loading…
Reference in New Issue
Block a user