Saving .tif stack with PIL/Image

Viewed 1248

I have a bunch of .tif images in a directory, and I am trying to open them using PIL and saving them as a single .tif file where each image is a frame. Which in principle should be possible according to this: https://github.com/python-pillow/Pillow/issues/3636#issuecomment-508058396

So far I got:

from PIL import Image

img_frames = ['test_imgs/img1.tif',
            'test_imgs/img2.tif',
            'test_imgs/img3.tif']

# read the images and store them in a list
ordered_image_files = []
for img in img_frames:
    with Image.open(img) as temp_img:
        ordered_image_files.append(temp_img)

# save the first image and add the rest as frames
ordered_image_files[0].save('test.tif', 
                            save_all = True, 
                            append_images = ordered_image_files[1:])

Running this gives me:

AttributeError: 'TiffImageFile' object has no attribute 'load_read'

If I print the image objects and their classes I get:

> print(ordered_image_files[0])
<PIL.TiffImagePlugin.TiffImageFile image mode=I;16B size=512x512 at 0x1028C6550>
> print(type(ordered_image_files[0]))
<class 'PIL.TiffImagePlugin.TiffImageFile'>

So I think the reading part is fine.

I am new to image processing so perhaps I am missing something obvious.

Thanks in advance.

Complete error trace:

Traceback (most recent call last):
  File "/Users/mpages/miniconda3/envs/denoise_n2v/lib/python3.6/site-packages/PIL/ImageFile.py", line 161, in load
    read = self.load_read
AttributeError: 'TiffImageFile' object has no attribute 'load_read'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "img_test.py", line 24, in <module>
    append_images = ordered_image_files[1:])
  File "/Users/mpages/miniconda3/envs/denoise_n2v/lib/python3.6/site-packages/PIL/Image.py", line 2050, in save
    self._ensure_mutable()
  File "/Users/mpages/miniconda3/envs/denoise_n2v/lib/python3.6/site-packages/PIL/Image.py", line 640, in _ensure_mutable
    self._copy()
  File "/Users/mpages/miniconda3/envs/denoise_n2v/lib/python3.6/site-packages/PIL/Image.py", line 633, in _copy
    self.load()
  File "/Users/mpages/miniconda3/envs/denoise_n2v/lib/python3.6/site-packages/PIL/TiffImagePlugin.py", line 1098, in load
    return super(TiffImageFile, self).load()
  File "/Users/mpages/miniconda3/envs/denoise_n2v/lib/python3.6/site-packages/PIL/ImageFile.py", line 165, in load
    read = self.fp.read
AttributeError: 'NoneType' object has no attribute 'read'

1 Answers

I believe your with statement is closing your image file or putting it out of some memory context in which it can be accessed, so you could try this which works fine on my Mac:

for img in img_frames: 
    ordered_image_files.append(Image.open(img)) 

Failing that, I had some success with the tifffile module, as follows:

import tifffile
img_frames = [ '1.tif', '2.tif', '3.tif' ]

with tifffile.TiffWriter('multipage.tif') as stack: 
    for filename in img_frames: 
        stack.save(tifffile.imread(filename))

Keywords: Python, TIF, TIFF, tifffile, multi-page, multipage, sequence, image, image processing

Related