我有一个原始图像,其中每个像素对应一个16位无符号整数。我试图使用PIL Image.fromstring()函数读取,如下面的代码所示:
if __name__ == "__main__":
if (len(sys.argv) != 4):
print 'Error: missing input argument'
sys.exit()
file = open(sys.argv[1], 'rb')
rawData = file.read()
file.close()
imgSize = (int(sys.argv[2]), int(sys.argv[3]))
# Use the PIL raw decoder to read the data.
# - the 'F;16' informs the raw decoder that we are reading a little endian, unsigned integer 16 bit data.
img = Image.fromstring('L', imgSize, rawData, 'raw', 'F;16')
im.save('out.png')
PIL文档通知fromstring()函数的第一个参数是'mode'。然而,看文档和谷歌搜索,我无法找到有关该论点真正意义的细节(我相信它与色彩空间或类似的东西有关)。有谁知道我在哪里可以找到关于fromstring()函数的更详细的参考以及mode参数的含义?
答案 0 :(得分:20)
具体文档位于http://effbot.org/imagingbook/concepts.htm:
模式
图像模式定义了类型 和图像中像素的深度。该 当前版本支持以下内容 标准模式:
- 1(1位像素,黑白,每字节存储一个像素)
- L(8位像素,黑白)
- P(8位像素,使用调色板映射到任何其他模式)
- RGB(3x8位像素,真彩色)
- RGBA(4x8位像素,带透明蒙版的真彩色)
- CMYK(4x8位像素,分色)
- YCbCr(3x8位像素,彩色视频格式)
- I(32位有符号整数像素)
- F(32位浮点像素)
PIL也提供有限的支持 一些特殊模式,包括LA(L 与alpha),RGBX(真正的颜色与 填充)和RGBa(真彩色 预乘alpha)。
答案 1 :(得分:10)
Image.frombuffer(mode,size,data)=>图像
(PIL 1.1.4中的新内容)。使用标准的“原始”解码器从字符串或缓冲区对象中的像素数据创建图像存储器。对于某些模式,图像存储器将与原始缓冲区共享存储器(这意味着对原始缓冲区对象的更改将反映在图像中)。并非所有模式都可以共享内存;支持的模式包括“L”,“RGBX”,“RGBA”和“CMYK”。对于其他模式,此函数的行为类似于对fromstring函数的相应调用。
我不确定“L”代表什么,但“RGBA”代表Red-Green-Blue-Alpha,所以我认为RGBX相当于RGB(编辑:测试时不是这样)? CMYK是Cyan-Magenta-Yellow-Kelvin,是另一种颜色空间。当然我假设如果你了解PIL你也知道色彩空间。如果没有,Wikipedia有一篇很棒的文章。
至于它的真正意义(如果这还不够):对于每个颜色空间,像素值将被不同地编码。在常规RGB中,每个像素有3个字节 - 0-254,0-254,0-254。对于Alpha,您可以为每个像素添加另一个字节。如果将RGB图像解码为RGBA,则最终会将第一个像素右侧的R像素读取为alpha,这意味着您将获得G像素作为R值。这将根据您的图像大小而放大,但它会让您的色彩变得难以置信。同样,尝试将CMYK编码的图像作为RGB(或RGBA)读取将使您的图像看起来非常不像它应该的那样。例如,尝试使用图像:
i = Image.open('image.png')
imgSize = i.size
rawData = i.tostring()
img = Image.fromstring('L', imgSize, rawData)
img.save('lmode.png')
img = Image.fromstring('RGB', imgSize, rawData)
img.save('rgbmode.png')
img = Image.fromstring('RGBX', imgSize, rawData)
img.save('rgbxmode.jfif')
img = Image.fromstring('RGBA', imgSize, rawData)
img.save('rgbamode.png')
img = Image.fromstring('CMYK', imgSize, rawData)
img.save('rgbamode.tiff')
你会看到不同模式的作用 - 尝试使用各种输入图像:png with alpha,png without alpha,bmp,gif和jpeg。实际上,这是一个有趣的实验。
答案 2 :(得分:5)
如果所有其他方法都失败了,您可以随时阅读源代码。对于PIL,下载量为here。
你从未说过16位无符号整数中的像素数据到底是什么格式,但我猜它有点像RRRRRGGGGGGBBBBBB,(5位红色,6位绿色,5位蓝色)或RRRRRGGGGGBBBBBA (5位红色,5位绿色,5位蓝色,1位Alpha或透明度)。在我自己快速浏览了一些来源之后,我没有看到对这些格式的支持,但是不能肯定地说一种方式。
在PIL下载的同一网页上,他们提到可以将问题发送到Python Image SIG邮件列表并为其提供链接。这可能比在这里询问更好。
希望这有帮助。
答案 3 :(得分:4)
这是一个老问题,但这可能会对将来有所帮助。原始代码段的一个问题是,在Image.fromstring('L', imgSize, rawData, 'raw', 'F;16')
中,F;16
部分适用于'F'
模式。
这对我有用:
image = Image.fromstring('F', imgSize, rawData, 'raw', 'F;16')
image.convert('L').save('out.png')