Repository navigation
Image.fromarray silently fails with floating-point input #2856
Description
Activity
My impression of this parameter (which, tbh, is not well documented) is that it's for overriding the mode that's detected from the dtype. Raising an error where it doesn't match is going to be problematical for the intended use case. On the other hand, since it's assigned directly to the rawmode as well as the mode, there are only a handful of valid modes that will work, generally the ones where the mode and rawmode match in the unpackers table in
libImaging/Unpack.c#4887 encountered this as well.
import numpy as np from PIL import Image array = np.full((32,32,3),255) Image.fromarray(array, "RGB")
And #5227
import numpy as np from PIL import Image vector = np.ones((5, 5, 3)).astype("uint8") * np.array([3]) Image.fromarray(vector, mode="RGB")
And #5465
import numpy as np from PIL import Image tgt = np.ones(shape=(2, 2)) # float32 tgt_im = Image.fromarray(tgt) tgt_im_np = np.asarray(tgt_im) final_img = Image.fromarray(tgt_im_np, mode='L') print(np.asarray(final_img))
If you remove the
modeparameter from the original post'sfromarraycall,from PIL import Image import numpy as np x = np.ones((100, 100), dtype='float64') x[40:60, 40:60] = 0.0 im = Image.fromarray(x) im.save("out.tiff")
then you get the expected result - out.tiff.zip
(Here is it converted to PNG since GitHub won't allow TIFFs)

I'm going to suggest resolving this by just improving the documentation in #5849
from PIL import Image import numpy as np a = np.zeros((200,200)) a[0:2,0:2] = 1 a[99:101,99:101] = 1 img = Image.fromarray(a,mode='L') img1 = np.array(img)
I find that a is a matrix with lots of zeros and 8 ones at the right position, but img1 is a wrong matrix. Wrong numbers 240 and 63 appears at strange positions:

There is no warning, I didn`t understand why this change happened until I see this issue.
I would like to know What data types and ranges are required for the different modes of Image.fromarray? I don't see this in the official documentation of pillow, can someone tell me? Did I mislocate the official documentation?
https://pillow-docs-cn.readthedocs.io/zh-cn/latest/reference/Image.html#PIL.Image.fromarray
Thanks!https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.fromarray is the official documentation.
The 'mode' parameter is optional. If you do not wish to tell Pillow to treat the data as a different mode, then you can just omit it.
You might also be interested in
Lines 3356 to 3380 in d66c51a
_fromarray_typemap = { # (shape, typestr) => mode, rawmode # first two members of shape are set to one ((1, 1), "|b1"): ("1", "1;8"), ((1, 1), "|u1"): ("L", "L"), ((1, 1), "|i1"): ("I", "I;8"), ((1, 1), "<u2"): ("I", "I;16"), ((1, 1), ">u2"): ("I", "I;16B"), ((1, 1), "<i2"): ("I", "I;16S"), ((1, 1), ">i2"): ("I", "I;16BS"), ((1, 1), "<u4"): ("I", "I;32"), ((1, 1), ">u4"): ("I", "I;32B"), ((1, 1), "<i4"): ("I", "I;32S"), ((1, 1), ">i4"): ("I", "I;32BS"), ((1, 1), "<f4"): ("F", "F;32F"), ((1, 1), ">f4"): ("F", "F;32BF"), ((1, 1), "<f8"): ("F", "F;64F"), ((1, 1), ">f8"): ("F", "F;64BF"), ((1, 1, 2), "|u1"): ("LA", "LA"), ((1, 1, 3), "|u1"): ("RGB", "RGB"), ((1, 1, 4), "|u1"): ("RGBA", "RGBA"), # shortcuts: ((1, 1), f"{_ENDIAN}i4"): ("I", "I"), ((1, 1), f"{_ENDIAN}f4"): ("F", "F"), } Thank you ! Do you mean that if I use
img = Image.fromarray(a)instead ofimg = Image.fromarray(a,mode='L'), I will get correct results?I expect so, yes.
Thank you very very much. Although Python's documentation isn't as comprehensive as MATLAB's and bugs do occur from time to time, I believe it's the presence of enthusiastic individuals like you – who actively help others by answering questions and solving problems – that keeps Python thriving with such vibrant vitality!
Reacted by Hugo van Kemenade and Jeffrey 'Alex' ClarkReacted by Jeffrey 'Alex' Clark
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