为何PIL会将两个数值完全相同的numpy数组渲染为不同的图片
问题成因
这个异常的核心原因是两个矩阵的数值相同但数据类型不同,PIL的图像解析逻辑对数据类型有强要求,而numpy的相等判断不校验数据类型:
- 原函数
createMatrix在调用np.full时显式指定了dtype=uint8,输出数组是符合PIL RGB模式要求的8位无符号整数,每个通道占1字节,取值范围0~255,解析逻辑正常。 - 修改后的
createMatrix1使用np.tile构造数组时没有指定数据类型,会继承输入bg参数的类型:当你传入Python原生整数组成的元组(0,0,0)作为背景时,np.tile生成的数组默认是int32/int64类型的有符号整数,每个元素占4字节。 np.array_equal仅对比两个数组的数值是否一致,不会校验数据类型,因此只要数值都是0和255就会判定相等。但PIL处理RGB模式时默认要求输入为8位无符号整数,传入32/64位整数时会错误拆分字节解析通道值,最终显示效果完全异常。
解决方案
只需要在createMatrix1中强制将输出数组的类型设置为uint8即可,修改后的代码如下:
def createMatrix1(w, h, bg, value, seq): # 把bg转成uint8类型再做tile,保证生成数组的类型正确 data = np.tile(np.array(bg, dtype=np.uint8), (h, w, 1)) rows = (seq-1)//w cols = (seq-1)%w if rows.size and cols.size: data[rows,cols] = value return data
也可以在np.tile调用结束后统一转换类型:
data = np.tile(bg, (h, w, 1)).astype(np.uint8)
修改后生成的数组数据类型和原函数一致,PIL就可以正常解析显示图像了。
内容的提问来源于stack exchange,提问作者Pigna
相关产品推荐
相关产品推荐

