Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Tests/test_file_gif.py
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,12 @@ def test_append_images(tmp_path: Path) -> None:
ims = [Image.new("RGB", (100, 100), color) for color in ["#0f0", "#00f"]]
im.copy().save(out, save_all=True, append_images=ims)

with Image.open(out) as reread:
assert reread.n_frames == 3

# Test append_images without save_all
im.copy().save(out, append_images=ims)

with Image.open(out) as reread:
assert reread.n_frames == 3

Expand Down
26 changes: 14 additions & 12 deletions docs/handbook/image-file-formats.rst
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,9 @@ following options are available::
im.save(out, save_all=True, append_images=[im1, im2, ...])

**save_all**
If present and true, all frames of the image will be saved. If
not, then only the first frame of a multiframe image will be saved.
If present and true, or if ``append_images`` is not empty, all frames of
the image will be saved. Otherwise, only the first frame of a multiframe
image will be saved.

**append_images**
A list of images to append as additional frames. Each of the
Expand Down Expand Up @@ -723,8 +724,8 @@ Saving

When calling :py:meth:`~PIL.Image.Image.save` to write an MPO file, by default
only the first frame of a multiframe image will be saved. If the ``save_all``
argument is present and true, then all frames will be saved, and the following
option will also be available.
argument is present and true, or if ``append_images`` is not empty, all frames
will be saved.

**append_images**
A list of images to append as additional pictures. Each of the
Expand Down Expand Up @@ -934,7 +935,8 @@ Saving

When calling :py:meth:`~PIL.Image.Image.save`, by default only a single frame PNG file
will be saved. To save an APNG file (including a single frame APNG), the ``save_all``
parameter must be set to ``True``. The following parameters can also be set:
parameter should be set to ``True`` or ``append_images`` should not be empty. The
following parameters can also be set:

**default_image**
Boolean value, specifying whether or not the base image is a default image.
Expand Down Expand Up @@ -1163,7 +1165,8 @@ Saving
The :py:meth:`~PIL.Image.Image.save` method can take the following keyword arguments:

**save_all**
If true, Pillow will save all frames of the image to a multiframe tiff document.
If true, or if ``append_images`` is not empty, Pillow will save all frames of the
image to a multiframe tiff document.

.. versionadded:: 3.4.0

Expand Down Expand Up @@ -1313,8 +1316,8 @@ Saving sequences

When calling :py:meth:`~PIL.Image.Image.save` to write a WebP file, by default
only the first frame of a multiframe image will be saved. If the ``save_all``
argument is present and true, then all frames will be saved, and the following
options will also be available.
argument is present and true, or if ``append_images`` is not empty, all frames
will be saved, and the following options will also be available.

**append_images**
A list of images to append as additional frames. Each of the
Expand Down Expand Up @@ -1616,15 +1619,14 @@ The :py:meth:`~PIL.Image.Image.save` method can take the following keyword argum
**save_all**
If a multiframe image is used, by default, only the first image will be saved.
To save all frames, each frame to a separate page of the PDF, the ``save_all``
parameter must be present and set to ``True``.
parameter should be present and set to ``True`` or ``append_images`` should not be
empty.

.. versionadded:: 3.0.0

**append_images**
A list of :py:class:`PIL.Image.Image` objects to append as additional pages. Each
of the images in the list can be single or multiframe images. The ``save_all``
parameter must be present and set to ``True`` in conjunction with
``append_images``.
of the images in the list can be single or multiframe images.

.. versionadded:: 4.2.0

Expand Down
1 change: 0 additions & 1 deletion docs/handbook/tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,6 @@ You can create animated GIFs with Pillow, e.g.
# Save the images as an animated GIF
images[0].save(
"animated_hopper.gif",
save_all=True,
append_images=images[1:],
duration=500, # duration of each frame in milliseconds
loop=0, # loop forever
Expand Down
8 changes: 6 additions & 2 deletions src/PIL/Image.py
Original file line number Diff line number Diff line change
Expand Up @@ -2527,13 +2527,17 @@ def save(
# may mutate self!
self._ensure_mutable()

save_all = params.pop("save_all", False)
save_all = params.pop("save_all", None)
self.encoderinfo = {**getattr(self, "encoderinfo", {}), **params}
self.encoderconfig: tuple[Any, ...] = ()

if format.upper() not in SAVE:
init()
if save_all:
if save_all or (
save_all is None
and params.get("append_images")
and format.upper() in SAVE_ALL
):
save_handler = SAVE_ALL[format.upper()]
else:
save_handler = SAVE[format.upper()]
Expand Down
Loading