使用Python 3.6将二维rgb矩阵转换为PNG图像

时间:2019-10-02 09:15:30

标签: python-3.x image matrix png data-conversion

我需要使用Python 3.6转换二维24位rgb-矩阵

[[rr11gg11bb11, rr12gg12bb12,..  ..,rr1mgg1mbb1m],
.
.
 [rri1gg11bb11, rr12ggi2bb12,..  ..,rr1mgg1mbb1m]
.
.
 [rrn1ggn1bbn1, rrn2ggn2bbn2,.. ..,rrmnggmnbbmn]]

转换为tif,png和jpg格式的图像。

我也得到了文件形式的矩阵

image.bin.

从这个二进制文件中,我可以借助RAW Pixel Viewer来处理图像:

http://rawpixels.net/ 

我已经找到了PIL库,但是我没有找到任何根据这些数据构建图像对象的方法。我怎样才能做到这一点?我使用的是Python 3.6。

现在我尝试了以下方法:

im = Image.frombuffer('RGB', (self.width, self.height), self.matrix, 'raw', 
'RGB', 0, 1)              
logger.info("image object created.")
im.save('result.png')
logger.info("image saved as result.png")

但是我得到消息:

TypeError: a bytes-like object is required, not 'list'

现在我发现必须将对象转换为字节数组:

 npm = np.array(self.matrix)
 arr = bytearray(npm)
 print(arr)
 im = Image.frombuffer('RGB', (self.width, self.height), arr, 'raw', 
'RGB', 0, 1)        

当我使用'L'或'RGBA'而不是'RGB'时,转换仅适用。奇怪的是,它拒绝一个字节数组对象。

1 个答案:

答案 0 :(得分:2)

更新后的答案

因此,从本质上讲,您没有Numpy数组,但是有一个列表列表,其中每个元素都是一个单个 24位数字,代表RGB三元组RGB888。

因此,我可以这样表示您的列表:

f=[ 
[0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x000000,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF],
[0xFFFFFF,0xFFFFFF,0xFFFFFF,0x000000,0x000000,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF],
[0xFFFFFF,0xFFFFFF,0x000000,0xFFFFFF,0x000000,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF],
[0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x000000,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF],
[0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x000000,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF]
] 

因此,我可以将其制成uint32元素的Numpy数组,如下所示:

na = np.array(f).astype(np.uint32) 

然后使用以下方法制作一个PIL想要的RGB阵列:

h,w = 5,10
RGB=np.zeros((h,w,3),dtype=np.uint8)

然后我只需要移动三元组并将其复制到正确的位置:

RGB[:,:,0] = na>>16            # Take red from top
RGB[:,:,1] = (na>>8) & 0xff    # Take green from middle
RGB[:,:,2] = na & 0xff         # Take blue from bottom

现在我可以从该RGB阵列制作一个PIL图像并将其保存到磁盘:

pIm = Image.fromarray(RGB).save('result.png')

原始答案

让我们使用 ImageMagick 创建测试数据文件。首先是PNG,以便您可以看到它:

magick -size 640x480 gradient:magenta-yellow image.png

enter image description here

现在又是同一件事,但是这次是与RGB888匹配的文件:

magick -size 640x480 gradient:magenta-yellow -depth 8 rgb:image.bin

现在:

from PIL import Image

# Open the file and read contents into "data"
with open('image.bin','rb') as f: 
    data = f.read() 

# Convert that into PIL Image
im = Image.frombuffer('RGB', (640, 480), data, 'raw', 'RGB', 0, 1)

# Save
im.save('result.png')

您同样可以让Numpy读取文件,然后将结果转换为PIL图像:

import numpy as np

im = Image.fromarray(np.fromfile('image.bin',dtype=np.uint8).reshape(480,640,3))

如果要检查二进制文件中实际包含的内容,还可以使用 ImageMagick 将其转换为PNG进行测试。假设您认为文件的宽度为640像素,高度为480像素,并且为RGB888,则可以要求 ImageMagick 将其制作为PNG文件,如下所示:

magick -depth 8 -size 640x480 RGB:<YOURFILENAME> image.png

或者,如果您认为这是一个带有128字节标头的16位单通道灰度图像,则要忽略:

magick -depth 16 -size 640x480+128 GRAY:<YOURFILENAME> image.png

关键字:原始,原始图像,二进制文件,图像,图像处理,Python,ImageMagick,转换。

相关问题