-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Closed
Labels
Milestone
Description
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:
Lines 2394 to 2438 in c82f9fe
| 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
Reactions are currently unavailable
