我目前处理此问题的方法是通过numpy:
- 将图像读取到2D
numpy
阵列中。您 不需要 使用numpy
,但是我发现它比常规的Python 2D数组更容易使用 PIL.Image
使用2D将numpy数组转换为对象PIL.Image.fromarray
如果您坚持使用
PIL.Image.open,则可以编写一个包装程序,尝试首先加载PGM文件(通过查看标头)。如果是PGM,请使用上述步骤加载图像,否则只需将责任移交给即可
PIL.Image.open。
这是一些我用来将 PBM 图像转换为numpy数组的代码。
import reimport numpydef pbm2numpy(filename): """ Read a PBM into a numpy array. only supports ASCII PBM for now. """ fin = None debug = True try: fin = open(filename, 'r') while True: header = fin.readline().strip() if header.startswith('#'): continue elif header == 'P1': break elif header == 'P4': assert False, 'Raw PBM reading not implemented yet' else: # # Unexpected header. # if debug: print 'Bad mode:', header return None rows, cols = 0, 0 while True: header = fin.readline().strip() if header.startswith('#'): continue match = re.match('^(d+) (d+)$', header) if match == None: if debug: print 'Bad size:', repr(header) return None cols, rows = match.groups() break rows = int(rows) cols = int(cols) assert (rows, cols) != (0, 0) if debug: print 'Rows: %d, cols: %d' % (rows, cols) # # Initialise a 2D numpy array # result = numpy.zeros((rows, cols), numpy.int8) pxs = [] # # Read to EOF. # while True: line = fin.readline().strip() if line == '': break for c in line: if c == ' ': continue pxs.append(int(c)) if len(pxs) != rows*cols: if debug: print 'Insufficient image data:', len(pxs) return None for r in range(rows): for c in range(cols): # # Index into the numpy array and set the pixel value. # result[r, c] = pxs[r*cols + c] return result finally: if fin != None: fin.close() fin = None return None您将不得不对其进行略微修改以适合您的目的,即:
- 处理P2(ASCII,灰度)而不是P1(ASCII,双电平)。
- 如果您不使用numpy,请使用其他容器。普通的Python 2D数组可以正常工作。
编辑
这是我处理包装纸的方法:
def pgm2pil(fname): # # This method returns a PIL.Image. Use pbm2numpy function above as a # guide. If it can't load the image, it returns None. # passdef wrapper(fname): pgm = pgm2pil(fname) if pgm is not None: return pgm return PIL.Image.open(fname)## This is the line that "adds" the wrapper#PIL.Image.open = wrapper
我没有写,
pgm2pil因为它会与非常相似
pgm2numpy。唯一的区别是它将结果存储在a
PIL.Image中而不是
numpy数组中。我也没有测试包装器代码(对不起,目前时间太短了),但这是一种相当普遍的方法,因此我希望它能正常工作。
现在,听起来您希望使用PIL进行图像加载的 其他 应用程序能够处理PGM。可以使用上述方法,但是您需要确保 在 第一次调用 之前
添加了以上包装器代码
PIL.Image.open。您可以通过将包装器源代码添加到PIL源代码中(如果您可以访问)来确保发生这种情况。



