mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-03-12 16:55:47 +03:00
Merge pull request #8780 from radarhere/save_all
Allow encoderconfig and encoderinfo to be set for appended TIFF images
This commit is contained in:
commit
00593ff3f8
|
@ -660,6 +660,18 @@ class TestFileTiff:
|
||||||
assert isinstance(im, TiffImagePlugin.TiffImageFile)
|
assert isinstance(im, TiffImagePlugin.TiffImageFile)
|
||||||
assert im.tag_v2[278] == 256
|
assert im.tag_v2[278] == 256
|
||||||
|
|
||||||
|
im = hopper()
|
||||||
|
im2 = Image.new("L", (128, 128))
|
||||||
|
im2.encoderinfo = {"tiffinfo": {278: 256}}
|
||||||
|
im.save(outfile, save_all=True, append_images=[im2])
|
||||||
|
|
||||||
|
with Image.open(outfile) as im:
|
||||||
|
assert isinstance(im, TiffImagePlugin.TiffImageFile)
|
||||||
|
assert im.tag_v2[278] == 128
|
||||||
|
|
||||||
|
im.seek(1)
|
||||||
|
assert im.tag_v2[278] == 256
|
||||||
|
|
||||||
def test_strip_raw(self) -> None:
|
def test_strip_raw(self) -> None:
|
||||||
infile = "Tests/images/tiff_strip_raw.tif"
|
infile = "Tests/images/tiff_strip_raw.tif"
|
||||||
with Image.open(infile) as im:
|
with Image.open(infile) as im:
|
||||||
|
|
|
@ -1163,9 +1163,7 @@ The :py:meth:`~PIL.Image.Image.save` method can take the following keyword argum
|
||||||
|
|
||||||
**append_images**
|
**append_images**
|
||||||
A list of images to append as additional frames. Each of the
|
A list of images to append as additional frames. Each of the
|
||||||
images in the list can be single or multiframe images. Note however, that for
|
images in the list can be single or multiframe images.
|
||||||
correct results, all the appended images should have the same
|
|
||||||
``encoderinfo`` and ``encoderconfig`` properties.
|
|
||||||
|
|
||||||
.. versionadded:: 4.2.0
|
.. versionadded:: 4.2.0
|
||||||
|
|
||||||
|
|
|
@ -2475,7 +2475,21 @@ class Image:
|
||||||
format to use is determined from the filename extension.
|
format to use is determined from the filename extension.
|
||||||
If a file object was used instead of a filename, this
|
If a file object was used instead of a filename, this
|
||||||
parameter should always be used.
|
parameter should always be used.
|
||||||
:param params: Extra parameters to the image writer.
|
:param params: Extra parameters to the image writer. These can also be
|
||||||
|
set on the image itself through ``encoderinfo``. This is useful when
|
||||||
|
saving multiple images::
|
||||||
|
|
||||||
|
# Saving XMP data to a single image
|
||||||
|
from PIL import Image
|
||||||
|
red = Image.new("RGB", (1, 1), "#f00")
|
||||||
|
red.save("out.mpo", xmp=b"test")
|
||||||
|
|
||||||
|
# Saving XMP data to the second frame of an image
|
||||||
|
from PIL import Image
|
||||||
|
black = Image.new("RGB", (1, 1))
|
||||||
|
red = Image.new("RGB", (1, 1), "#f00")
|
||||||
|
red.encoderinfo = {"xmp": b"test"}
|
||||||
|
black.save("out.mpo", save_all=True, append_images=[red])
|
||||||
:returns: None
|
:returns: None
|
||||||
:exception ValueError: If the output format could not be determined
|
:exception ValueError: If the output format could not be determined
|
||||||
from the file name. Use the format option to solve this.
|
from the file name. Use the format option to solve this.
|
||||||
|
|
|
@ -2295,9 +2295,7 @@ class AppendingTiffWriter(io.BytesIO):
|
||||||
|
|
||||||
|
|
||||||
def _save_all(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
|
def _save_all(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
|
||||||
encoderinfo = im.encoderinfo.copy()
|
append_images = list(im.encoderinfo.get("append_images", []))
|
||||||
encoderconfig = im.encoderconfig
|
|
||||||
append_images = list(encoderinfo.get("append_images", []))
|
|
||||||
if not hasattr(im, "n_frames") and not append_images:
|
if not hasattr(im, "n_frames") and not append_images:
|
||||||
return _save(im, fp, filename)
|
return _save(im, fp, filename)
|
||||||
|
|
||||||
|
@ -2305,12 +2303,11 @@ def _save_all(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
|
||||||
try:
|
try:
|
||||||
with AppendingTiffWriter(fp) as tf:
|
with AppendingTiffWriter(fp) as tf:
|
||||||
for ims in [im] + append_images:
|
for ims in [im] + append_images:
|
||||||
ims.encoderinfo = encoderinfo
|
if not hasattr(ims, "encoderinfo"):
|
||||||
ims.encoderconfig = encoderconfig
|
ims.encoderinfo = {}
|
||||||
if not hasattr(ims, "n_frames"):
|
if not hasattr(ims, "encoderconfig"):
|
||||||
nfr = 1
|
ims.encoderconfig = ()
|
||||||
else:
|
nfr = getattr(ims, "n_frames", 1)
|
||||||
nfr = ims.n_frames
|
|
||||||
|
|
||||||
for idx in range(nfr):
|
for idx in range(nfr):
|
||||||
ims.seek(idx)
|
ims.seek(idx)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user