我该如何为 Python Imaging Library 编写一个针对 PGM 纯 ASCII 格式(P2)的过滤器呢?问题在于,基本的 PIL 过滤器假定每个像素有恒定的字节数。
我的目标是使用 Image.open() 打开 feep.pgm。请参见http://netpbm.sourceforge.net/doc/pgm.html 或下方链接获得更多信息。
另一个解决方案是找到其他受 PIL 和所有主要图形程序支持的良好记录的灰度 ASCII 格式。有什么建议吗?
feep.pgm:
P2
# feep.pgm
24 7
15
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 3 3 3 3 0 0 7 7 7 7 0 0 11 11 11 11 0 0 15 15 15 15 0
0 3 0 0 0 0 0 7 0 0 0 0 0 11 0 0 0 0 0 15 0 0 15 0
0 3 3 3 0 0 0 7 7 7 0 0 0 11 11 11 0 0 0 15 15 15 15 0
0 3 0 0 0 0 0 7 0 0 0 0 0 11 0 0 0 0 0 15 0 0 0 0
0 3 0 0 0 0 0 7 7 7 7 0 0 11 11 11 11 0 0 15 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
编辑:谢谢您的回答,它有效...但是我需要使用Image.open()的解决方案。大多数Python程序都使用PIL进行图形处理(搜索:python image open)。因此,我需要能够向PIL注册滤镜。然后,我可以使用任何使用PIL的软件,如scipy、pylab等依赖程序。
编辑:好的,我现在明白了。下面是包装器pgm2pil.py:
import Image
import numpy
def pgm2pil(filename):
try:
inFile = open(filename)
header = None
size = None
maxGray = None
data = []
for line in inFile:
stripped = line.strip()
if stripped[0] == '#':
continue
elif header == None:
if stripped != 'P2': return None
header = stripped
elif size == None:
size = map(int, stripped.split())
elif maxGray == None:
maxGray = int(stripped)
else:
for item in stripped.split():
data.append(int(item.strip()))
data = numpy.reshape(data, (size[1],size[0]))/float(maxGray)*255
return numpy.flipud(data)
except:
pass
return None
def imageOpenWrapper(fname):
pgm = pgm2pil(fname)
if pgm is not None:
return Image.fromarray(pgm)
return origImageOpen(fname)
origImageOpen = Image.open
Image.open = imageOpenWrapper
对于misha的回答稍作修改。必须保存Image.open以防止无限循环。如果pgm2pil返回None,则包装器调用pgm2pil,pgm2pil返回None,然后调用pgm2pil...
下面是测试函数(feep_false.pgm是格式不正确的pgm,例如“P2”->“FOO”,而lena.pgm只是图像文件):
import pgm2pil
import pylab
try:
pylab.imread('feep_false.pgm')
except IOError:
pass
else:
raise ValueError("feep_false should fail")
pylab.subplot(2,1,1)
a = pylab.imread('feep.pgm')
pylab.imshow(a)
pylab.subplot(2,1,2)
b = pylab.imread('lena.png')
pylab.imshow(b)
pylab.show()