如何使用PIL读取原始图像?
我有一张原始图像,每个像素对应一个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参数的更详细的参考资料?
4 个回答
如果其他方法都不行,你总是可以看看源代码。关于PIL的下载链接在这里。
你没有具体说明16位无符号整数的像素数据是什么格式,但我猜可能是像这样:RRRRRGGGGGGBBBBBB(红色5位,绿色6位,蓝色5位),或者是RRRRRGGGGGBBBBBA(红色5位,绿色5位,蓝色5位,透明度1位)。我自己快速看了一下源代码,没有发现对这些格式的支持,但也不能确定。
在PIL下载的同一网页上,他们提到可以把问题发到Python图像特别兴趣小组的邮件列表,并提供了链接。那可能比在这里问更有帮助。
希望这些信息对你有帮助。
Image.frombuffer(mode, size, data) => image
(在PIL 1.1.4中新增)这个函数可以从一个字符串或缓冲区对象中的像素数据创建一个图像内存,使用的是标准的“原始”解码器。对于某些模式,图像内存会和原始缓冲区共享内存(这意味着对原始缓冲区的修改会反映在图像上)。并不是所有模式都可以共享内存;支持的模式包括“L”、“RGBX”、“RGBA”和“CMYK”。对于其他模式,这个函数的行为就像调用fromstring函数一样。
我不太确定“L”代表什么,但“RGBA”代表红色-绿色-蓝色-透明度,所以我猜RGBX和RGB是一样的(编辑:经过测试发现并不是这样)。CMYK是青色-品红色-黄色-黑色,这是一种不同的颜色空间。当然,我假设如果你了解PIL,你也知道颜色空间。如果不知道,可以查看维基百科上的一篇很好的文章。
至于这到底意味着什么(如果这些还不够):每种颜色空间的像素值编码方式是不同的。在普通的RGB中,每个像素有3个字节 - 0-254,0-254,0-254。对于透明度(Alpha),每个像素还要加一个字节。如果你把一个RGB图像解码成RGBA格式,你会把第一个像素右边的R像素当作透明度,这样你就会把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、没有透明度的png、bmp、gif和jpeg。其实这还挺有趣的实验。
具体的文档可以在这里找到:http://effbot.org/imagingbook/concepts.htm:
模式
图像的模式决定了图像中每个像素的类型和深度。当前版本支持以下标准模式:
- 1(1位像素,黑白,存储时每个像素占用一个字节)
- L(8位像素,黑白)
- P(8位像素,使用调色板映射到其他模式)
- RGB(3个8位像素,真彩色)
- RGBA(4个8位像素,真彩色并带透明度)
- CMYK(4个8位像素,颜色分离)
- YCbCr(3个8位像素,颜色视频格式)
- I(32位有符号整数像素)
- F(32位浮点像素)
PIL还对一些特殊模式提供有限支持,包括LA(带透明度的L)、RGBX(真彩色并带填充)和RGBa(带预乘透明度的真彩色)。