When passing a floating-point array to Image.fromarray, the output does not match the input:
from PIL import Image
import numpy as np
x = np.ones((100, 100), dtype='float64')
x[40:60, 40:60] = 0.0
Image.fromarray(x, mode='L')

This happens is because when mode is specified, the array's bytes are passed directly to frombuffer without any type check:
|
def fromarray(obj, mode=None): |
|
""" |
|
Creates an image memory from an object exporting the array interface |
|
(using the buffer protocol). |
|
|
|
If obj is not contiguous, then the tobytes method is called |
|
and :py:func:`~PIL.Image.frombuffer` is used. |
|
|
|
:param obj: Object with array interface |
|
:param mode: Mode to use (will be determined from type if None) |
|
See: :ref:`concept-modes`. |
|
:returns: An image object. |
|
|
|
.. versionadded:: 1.1.6 |
|
""" |
|
arr = obj.__array_interface__ |
|
shape = arr['shape'] |
|
ndim = len(shape) |
|
strides = arr.get('strides', None) |
|
if mode is None: |
|
try: |
|
typekey = (1, 1) + shape[2:], arr['typestr'] |
|
mode, rawmode = _fromarray_typemap[typekey] |
|
except KeyError: |
|
# print(typekey) |
|
raise TypeError("Cannot handle this data type") |
|
else: |
|
rawmode = mode |
|
if mode in ["1", "L", "I", "P", "F"]: |
|
ndmax = 2 |
|
elif mode == "RGB": |
|
ndmax = 3 |
|
else: |
|
ndmax = 4 |
|
if ndim > ndmax: |
|
raise ValueError("Too many dimensions: %d > %d." % (ndim, ndmax)) |
|
|
|
size = shape[1], shape[0] |
|
if strides is not None: |
|
if hasattr(obj, 'tobytes'): |
|
obj = obj.tobytes() |
|
else: |
|
obj = obj.tostring() |
|
|
|
return frombuffer(mode, size, obj, "raw", rawmode, 0, 1) |
It would be helpful for users if the dtype of the input were checked, and an appropriate warning or error raised.
I'm using Python 3.6.1 and PIL v4.2.1
When passing a floating-point array to
Image.fromarray, the output does not match the input:This happens is because when
modeis specified, the array's bytes are passed directly tofrombufferwithout any type check:Pillow/PIL/Image.py
Lines 2394 to 2438 in c82f9fe
It would be helpful for users if the dtype of the input were checked, and an appropriate warning or error raised.
I'm using Python 3.6.1 and PIL v4.2.1