mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-11-04 09:57:43 +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 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:
 | 
			
		||||
        infile = "Tests/images/tiff_strip_raw.tif"
 | 
			
		||||
        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**
 | 
			
		||||
    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
 | 
			
		||||
    correct results, all the appended images should have the same
 | 
			
		||||
    ``encoderinfo`` and ``encoderconfig`` properties.
 | 
			
		||||
    images in the list can be single or multiframe images.
 | 
			
		||||
 | 
			
		||||
    .. versionadded:: 4.2.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2475,7 +2475,21 @@ class Image:
 | 
			
		|||
           format to use is determined from the filename extension.
 | 
			
		||||
           If a file object was used instead of a filename, this
 | 
			
		||||
           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
 | 
			
		||||
        :exception ValueError: If the output format could not be determined
 | 
			
		||||
           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:
 | 
			
		||||
    encoderinfo = im.encoderinfo.copy()
 | 
			
		||||
    encoderconfig = im.encoderconfig
 | 
			
		||||
    append_images = list(encoderinfo.get("append_images", []))
 | 
			
		||||
    append_images = list(im.encoderinfo.get("append_images", []))
 | 
			
		||||
    if not hasattr(im, "n_frames") and not append_images:
 | 
			
		||||
        return _save(im, fp, filename)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2305,12 +2303,11 @@ def _save_all(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
 | 
			
		|||
    try:
 | 
			
		||||
        with AppendingTiffWriter(fp) as tf:
 | 
			
		||||
            for ims in [im] + append_images:
 | 
			
		||||
                ims.encoderinfo = encoderinfo
 | 
			
		||||
                ims.encoderconfig = encoderconfig
 | 
			
		||||
                if not hasattr(ims, "n_frames"):
 | 
			
		||||
                    nfr = 1
 | 
			
		||||
                else:
 | 
			
		||||
                    nfr = ims.n_frames
 | 
			
		||||
                if not hasattr(ims, "encoderinfo"):
 | 
			
		||||
                    ims.encoderinfo = {}
 | 
			
		||||
                if not hasattr(ims, "encoderconfig"):
 | 
			
		||||
                    ims.encoderconfig = ()
 | 
			
		||||
                nfr = getattr(ims, "n_frames", 1)
 | 
			
		||||
 | 
			
		||||
                for idx in range(nfr):
 | 
			
		||||
                    ims.seek(idx)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user