diff --git a/PIL/TiffImagePlugin.py b/PIL/TiffImagePlugin.py index 505025bb8..ede267c43 100644 --- a/PIL/TiffImagePlugin.py +++ b/PIL/TiffImagePlugin.py @@ -1737,17 +1737,28 @@ class AppendingTiffWriter: self.rewriteLastLong(offset) def _save_all(im, fp, filename): - if not hasattr(im, "n_frames"): + encoderinfo = im.encoderinfo.copy() + encoderconfig = im.encoderconfig + append_images = encoderinfo.get("append_images", []) + if not hasattr(im, "n_frames") and not len(append_images): return _save(im, fp, filename) cur_idx = im.tell() try: with AppendingTiffWriter(fp) as tf: - for idx in range(im.n_frames): - im.seek(idx) - im.load() - _save(im, tf, filename) - tf.newFrame() + 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 + + for idx in range(nfr): + ims.seek(idx) + ims.load() + _save(ims, tf, filename) + tf.newFrame() finally: im.seek(cur_idx) diff --git a/Tests/test_file_tiff.py b/Tests/test_file_tiff.py index 1fe3ad45e..1dfd0620c 100644 --- a/Tests/test_file_tiff.py +++ b/Tests/test_file_tiff.py @@ -473,6 +473,18 @@ class TestFileTiff(PillowTestCase): with Image.open(mp) as im: self.assertEqual(im.n_frames, 3) + # Test appending images + mp = io.BytesIO() + im = Image.new('RGB', (100, 100), '#f00') + ims = [Image.new('RGB', (100, 100), color) for color + in ['#0f0', '#00f']] + im.save(mp, format="TIFF", save_all=True, append_images=ims) + + mp.seek(0, os.SEEK_SET) + reread = Image.open(mp) + self.assertEqual(reread.n_frames, 3) + + def test_saving_icc_profile(self): # Tests saving TIFF with icc_profile set. # At the time of writing this will only work for non-compressed tiffs