How to write a filter for python image library for pgm plain ascii format (P2). The problem here is that the main PIL filter assumes a constant number of bytes per pixel.
My goal is to open feep.pgm with Image.open (). See http://netpbm.sourceforge.net/doc/pgm.html or below.
An alternative solution is that I find another well-documented ascii grayscale format that is supported by PIL and all major graphics programs. Any suggestions?
feep.pgm:
P2
edit: Thanks for the answer, it works ... but I need a solution that uses Image.open (). Most python programs use PIL to manipulate graphics (google: python image open). Thus, I need to be able to register a filter for PIL. Then I can use any software using PIL. Now I think mostly scipy, pylab, etc. Dependent programs.
edit Ok, I think I get it now. Below is the pgm2pil.py wrapper:
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
There is a small update for misha's answer. Image.open must be saved to prevent endless contours. If pgm2pil returns None, then the wrapper calls pgm2pil, which returns None, which calls pgm2pil ...
The following is a test function (feep_false.pgm is the wrong pgm, for example, "P2" → "FOO", and lena.pgm is just an image file ):
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()