Reputation: 1936
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
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