我有一个数组(numpy)的形状(10000,1296),我想保存为10,000张36x36大小的图像。数组中的所有值都在(0,255)
范围内。所以我用这个代码做了(效果很好):
for i, line in enumerate(myarray):
img = Image.new('L',(36,36))
img.putdata(line)
img.save(str(i)+'.png')
我想使用Image.fromarray
方法替换此代码,但与原始方法相比,生成的图片会失真,无法识别。首先我尝试了这个:
myarray = myarray.reshape(10000,36,36)
for i, line in enumerate(myarray):
img = Image.fromarray(line, 'L')
img.save(str(i)+'.png')
哪个不起作用。所以要调试我以为我会尝试一个项目并做到这一点:
Image.fromarray(myarray[0].reshape(36,36), 'L').save('test.png')
再次 - 乱码的图像乱码。
所以我认为fromarray
不能像我认为的那样工作,或者我的reshape
太天真并且弄乱了数据,但我无法解决这个问题。欢迎任何想法。
答案 0 :(得分:2)
PIL&lt; <div id="all-the-coordinates"></div>
模式是表示亮度的数据的灰度模式
(亮度)。预计数据的整数为0到255.如果通过将NumPy数组传递给L
Image.fromarray
来创建PIL图像,则数组的dtype应为mode='L'
。因此使用
uint8
确保传递给myarray = myarray.astype('uint8')
的数组具有dtype Image.fromarray
。
uint8
是无符号的8位整数。 uint8
是32位浮点数。它们是float32
的4倍宽。 uint8
将NumPy数组中的基础数据视为Image.fromarray
,读取足够的字节以填充图像,并忽略其余数据。因此,每个32位浮点数变为四个8位整数,每个8位整数颜色都是不同的像素。
换句话说,以下uint8
次传递:
assert
这就是为什么在不转换为import numpy as np
from PIL import Image
line = np.arange(256).reshape(16, 16).astype('float32')
img = Image.fromarray(line, 'L')
line2 = np.asarray(img)
assert (line.view('uint8').ravel()[:256].reshape(16, 16) == line2).all()
的情况下使用myarray
会产生乱码图像。
或者,您可以将uint8
转换为myarray
,而不是将其转换为uint8
读取mode='F'
中的数据(浮点模式):
import numpy as np
from PIL import Image
line = np.arange(256).reshape(16, 16).astype('float32')
img = Image.fromarray(line, 'F').convert('L')
img.save('/tmp/out.png')
产生
有关所有可能的PIL模式的列表,请参阅this page。