Jonathan
Jonathan

Reputation: 1936

Unable to save tiff images in python

I am trying to save an Image object as a .tif image with the following code:

path = ['../data/', str(i-10)]
mask_path = ['../data/', str(i-10), '_mask']
collage = Image.fromarray(collage, 'L')
collage_mask = Image.fromarray(collage_mask, '1')
collage.save(path, 'tiff')
collage_mask.save(mask_path, 'tiff')

Once I call the Image.fromarray() function, it becomes an Image object, so I don't understand why the save() call doesn't work. I get the following error:

AttributeError                            Traceback (most recent call last)
<ipython-input-103-350cd5436fc3> in <module>()
     14         collage = Image.fromarray(collage, 'L')
     15         collage_mask = Image.fromarray(collage_mask, '1')
---> 16         collage.save(path, 'tiff')
     17         collage_mask.save(mask_path, 'tiff')

~\Anaconda3\lib\site-packages\PIL\Image.py in save(self, fp, format, **params)
   1928 
   1929         try:
-> 1930             save_handler(self, fp, filename)
   1931         finally:
   1932             # do what we can to clean up

~\Anaconda3\lib\site-packages\PIL\TiffImagePlugin.py in _save(im, fp, filename)
   1523 
   1524     else:
-> 1525         offset = ifd.save(fp)
   1526 
   1527         ImageFile._save(im, fp, [

~\Anaconda3\lib\site-packages\PIL\TiffImagePlugin.py in save(self, fp)
    745     def save(self, fp):
    746 
--> 747         if fp.tell() == 0:  # skip TIFF header on subsequent pages
    748             # tiff header -- PIL always starts the first IFD at offset 8
    749             fp.write(self._prefix + self._pack("HL", 42, 8))

AttributeError: 'list' object has no attribute 'tell'

I also tried removing the second argument into save and just hard coding it into the path and mask_path variables. But that didn't work either. I tried plt.(path, collage, cmap = cm.gray) and I removed the Image.fromarray() calls as I didn't need to convert them to an Image object if I'm using matplotlib. But that created the following error: object does not appear to be a 8-bit string path or a Python file-like object

Upvotes: 1

Views: 1037

Answers (1)

abarnert
abarnert

Reputation: 366003

The problem has nothing to do with your second argument, but your first argument:

path = ['../data/', str(i-10)]
collage.save(path, 'tiff')

The first argument to Image.save is a filename, or an open file. But you're passing it a list.

I'm not sure what you're trying to accomplish here. If you want a path like ../data/1, you need to build a string, not a list of part of that string and a number as a separate thing. Maybe this:

path = f'../data/{i-10}'

Or this:

path = os.path.join('../data/', str(i-10))

If you want to understand the traceback, because it is a little confusing… What Pillow is doing here it that it first tries to treat your argument as a filename, then, if that doesn't work, it tries to treat it as a file object. So the exception you get back is about you list not working like a file object. You probably never expected it to work like a file object, but rather like a filename, so this understandably baffles you. Maybe it would be better if Pillow handled that error by converting it to a more informative one. But generally, APIs like Pillow's, which try to work for a variety of different types that have to be handled in different ways, are hard to write good error handling for.

Upvotes: 1

Related Questions