You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pillow的Image.fromarray方法异常:生成图像与原numpy数组不符求助

问题解决:Numpy单位数组转Pillow图像后对角线丢失

问题重现

创建10×10的Numpy单位矩阵:

x = np.eye(10, dtype=np.uint8)

输出数组:

[[1 0 0 0 0 0 0 0 0 0]
 [0 1 0 0 0 0 0 0 0 0]
 [0 0 1 0 0 0 0 0 0 0]
 [0 0 0 1 0 0 0 0 0 0]
 [0 0 0 0 1 0 0 0 0 0]
 [0 0 0 0 0 1 0 0 0 0]
 [0 0 0 0 0 0 1 0 0 0]
 [0 0 0 0 0 0 0 1 0 0]
 [0 0 0 0 0 0 0 0 1 0]
 [0 0 0 0 0 0 0 0 0 1]]

使用Pillow转换为图像并转回数组后,仅剩下一个1:

im = Image.fromarray(x, mode='1')
img_arr = np.array(im, dtype=np.uint8)

输出转回的数组:

[[0 0 0 0 0 0 0 1 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]]

完整代码:

import numpy as np
from PIL import Image, ImageOps

x = np.eye(10, dtype=np.uint8)
print(x)

im = Image.fromarray(x, mode='1')
im.show()
im.save("D:\Desktop/fig.jpeg")
print(im.mode)

img_arr = np.array(im, dtype=np.uint8)

print(img_arr)

原因分析

Pillow的mode='1'是1位二值图像模式,从uint8数组转换时,会以127为阈值:

  • 数组值≤127:被判定为黑色(对应二进制0)
  • 数组值>127:被判定为白色(对应二进制1)

原数组中对角线的1是uint8类型,值远小于127,因此全部被判定为黑色(0)。转回数组时出现的单个1是1位图像按字节存储的对齐冗余位,并非有效像素。

解决方法

方法1:将数组值替换为255

把原数组中的1替换为255(uint8的最大值),确保超过阈值127:

x = np.eye(10, dtype=np.uint8) * 255
im = Image.fromarray(x, mode='1')

方法2:使用布尔类型数组

直接创建布尔数组,Pillow的mode='1'会直接将True视为白色,False视为黑色:

x = np.eye(10, dtype=bool)
im = Image.fromarray(x, mode='1')

方法3:使用灰度模式(mode='L')

如果不需要严格的1位二值图像,可以使用8位灰度模式,此时1会显示为暗灰色,255为纯白色:

x = np.eye(10, dtype=np.uint8) * 255
im = Image.fromarray(x)  # 自动推断mode为'L'

内容的提问来源于stack exchange,提问作者AB Music Box

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 08:24:17