使用 Python 将二维 rgb 矩阵转换为 PNG 图像 3.6
Conversion 2-dimensional rgb matrix to PNG Image with Python 3.6
我需要用 Python 3.6
转换一个 2 维 24 位 rgb- 矩阵
[[rr11gg11bb11, rr12gg12bb12,.. ..,rr1mgg1mbb1m],
.
.
[rri1gg11bb11, rr12ggi2bb12,.. ..,rr1mgg1mbb1m]
.
.
[rrn1ggn1bbn1, rrn2ggn2bbn2,.. ..,rrmnggmnbbmn]]
转换成tif、png、jpg格式的图片。
我还得到了文件形式的矩阵
image.bin.
从这个二进制文件中,我可以借助 RAW Pixel Viewer 对图像进行 whatch:
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' 时,转换有效。奇怪的是,在这种情况下,它拒绝字节数组对象。
更新答案
所以,本质上,您没有 Numpy 数组,但是您有一个列表列表,其中每个元素都是一个 单个 表示 RGB 三元组的 24 位数字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
现在又是同样的事情,但这次是 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 像素宽 x 480 像素高和 RGB888,您可以要求 ImageMagick 将其转换为 PNG 格式:
magick -depth 8 -size 640x480 RGB:<YOURFILENAME> image.png
或者,如果您认为它是一个 128 字节的单通道灰度图像 header,您希望忽略它:
magick -depth 16 -size 640x480+128 GRAY:<YOURFILENAME> image.png
关键词: Raw, raw image, binary file, image, image processing, Python, ImageMagick, convert.
我需要用 Python 3.6
转换一个 2 维 24 位 rgb- 矩阵[[rr11gg11bb11, rr12gg12bb12,.. ..,rr1mgg1mbb1m],
.
.
[rri1gg11bb11, rr12ggi2bb12,.. ..,rr1mgg1mbb1m]
.
.
[rrn1ggn1bbn1, rrn2ggn2bbn2,.. ..,rrmnggmnbbmn]]
转换成tif、png、jpg格式的图片。
我还得到了文件形式的矩阵
image.bin.
从这个二进制文件中,我可以借助 RAW Pixel Viewer 对图像进行 whatch:
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' 时,转换有效。奇怪的是,在这种情况下,它拒绝字节数组对象。
更新答案
所以,本质上,您没有 Numpy 数组,但是您有一个列表列表,其中每个元素都是一个 单个 表示 RGB 三元组的 24 位数字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
现在又是同样的事情,但这次是 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 像素宽 x 480 像素高和 RGB888,您可以要求 ImageMagick 将其转换为 PNG 格式:
magick -depth 8 -size 640x480 RGB:<YOURFILENAME> image.png
或者,如果您认为它是一个 128 字节的单通道灰度图像 header,您希望忽略它:
magick -depth 16 -size 640x480+128 GRAY:<YOURFILENAME> image.png
关键词: Raw, raw image, binary file, image, image processing, Python, ImageMagick, convert.