Repository navigation
Description
Floating point images from numpy arrays via the PIL.Image.fromarray() raise an unclear error when accidentally returned in jupyter notebook as the final line in a cell. This triggers IPython.display.display() on the image object, which in turn calls the image object _repr_png_() method, which raises the error below.
What did you do?
Called
import numpy as np
from PIL.Image import fromarray
fromarray(np.random.random((30, 30)))What did you expect to happen?
Either:
A) Attempt to show the image given some defaults (like showing the image on a 8bit depth (resulting in a black image or very dark image)
B) More likely: Raise a clear error saying that you can't create images out of floating point values, and should instead (probably rescale to an appropriate bitdepth range and) change the dtype to be uint8 or some other accepted dtype.
What actually happened?
I get an error about how one cannot write mode F as png:
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
~\Miniconda3\envs\py\lib\site-packages\PIL\PngImagePlugin.py in _save(im, fp, filename, chunk, save_all)
1219 try:
-> 1220 rawmode, mode = _OUTMODES[mode]
1221 except KeyError as e:
KeyError: 'F'
The above exception was the direct cause of the following exception:
OSError Traceback (most recent call last)
~\Miniconda3\envs\py\lib\site-packages\IPython\core\formatters.py in __call__(self, obj)
343 method = get_real_method(obj, self.print_method)
344 if method is not None:
--> 345 return method()
346 return None
347 else:
~\Miniconda3\envs\py\lib\site-packages\PIL\Image.py in _repr_png_(self)
671 """
672 b = io.BytesIO()
--> 673 self.save(b, "PNG")
674 return b.getvalue()
675
~\Miniconda3\envs\py\lib\site-packages\PIL\Image.py in save(self, fp, format, **params)
2149
2150 try:
-> 2151 save_handler(self, fp, filename)
2152 finally:
2153 # do what we can to clean up
~\Miniconda3\envs\py\lib\site-packages\PIL\PngImagePlugin.py in _save(im, fp, filename, chunk, save_all)
1220 rawmode, mode = _OUTMODES[mode]
1221 except KeyError as e:
-> 1222 raise OSError(f"cannot write mode {mode} as PNG") from e
1223
1224 #
OSError: cannot write mode F as PNGWhat are your OS, Python and Pillow versions?
- OS: Win 10
- Python: 3.9
- Pillow: 8.0.1
Activity
radarhere commentedon Dec 21, 2020
For A, you may be interested in #2663 and the suggested PR #3172. The idea is that you could append
convert_mode=Trueand it would then convert automatically if saving wasn't possible.radarhere commentedon Dec 27, 2020
For B, you're asking for specific error messages for IPython, which I don't think can be neatly added in while keeping the other uses of Pillow in mind - in any other situation, the user might see this error message and just pick a format other than PNG.
#5139 is the best I personally have to offer, adding an error explaining that Pillow was trying to saving to PNG for display.
thomasaarholt commentedon Dec 29, 2020
Thanks :)
radarhere commentedon Jul 23, 2023
Be aware that #7266 is now proposing an alternative to this - capturing any errors and returning
Noneinstead.