I'm trying to read in a FITs image file for my research, and I decided that writing a file decoder for the Python imaging library would be the easiest way to accomplish this for my needs. FITs is a raw data format used in astronomy.
Anyway, I followed the example in the PIL documentation online, and I also had a look at the FITs image stub file included with PIL 1.1.5. I cooked up something that should work (or nearly work), but I keep running into either one of two errors (below). The crux of the problem appears to be that my plugin isn't being registered properly and isn't being read at runtime when I call Image.open(). 1.) The library loads the FitsStubImagePlugin.py file from the site-packages directory (instead of my plugin) and then gives the following error: File "/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/site-packages/PIL/ImageFile.py", line 255, in load raise IOError("cannot find loader for this %s file" % self.format) IOError: cannot find loader for this FITS file 2.) I remove the FitsStubImagePlugin.py, pyc files and stick my plugin in the directory instead (my plugin was already in the PYTHONPATH before). Then I get the following error: Traceback (most recent call last): File "FitsImagePlugin.py", line 111, in ? image = Image.open(fits_name).save(jpg_name) File "/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/site-packages/PIL/Image.py", line 1745, in open raise IOError("cannot identify image file") IOError: cannot identify image file This seems like I'm either doing (or not doing) something really stupid or the docs are outdated. Any help would be greatly appreciated! Jeremy ------------------------------ Code below ----------------------------------- import Image, ImageFile _handler = None ## # Install application-specific FITS image handler. # # @param handler Handler object. def register_handler(handler): global _handler _handler = handler # -------------------------------------------------------------------- # Image adapter def _accept(prefix): return prefix[:6] == "SIMPLE" class FitsImageFile(ImageFile.StubImageFile): #class FitsImageFile(ImageFile.ImageFile): format = "FITS" format_description = "FITs raw image" def _open(self): # byte offset for FITs images byte_offset = 2880 # check header for valid FITs image header_data = self.fp.read(byte_offset) # headers are stored in 80 character strings, so sort them out into a # nice list i = 0 headers = [] while header_data[i] != "\n" and i < len(header_data): headers.append(header_data[i:i + 80]) i += 81 # parse individual headers ok = False for header in headers: words = header.split() try: keyword = words[0] value = words[2] except IndexError: ok = False break if keyword == "NAXIS" and value == 2: ok = True elif keyword == "NAXIS1": xsize = value elif keyword == "NAXIS2": ysize = value if not ok: raise ValueError("file is not a valid FITs image") # size in pixels (width, height) self.size = (xsize, ysize) # mode setting is always greyscale self.mode = "F" # data descriptor self.tile = [("raw", (0, 0) + self.size, byte_offset, ("F", 0, -1))] # is this needed? loader = self._load() if loader: loader.open(self) def _load(self): return _handler def _save(im, fp, filename): if _handler is None or not hasattr("_handler", "save"): raise IOError("FITS save handler not installed") _handler.save(im, fp, filename) # register the plugin Image.register_open(FitsImageFile.format, FitsImageFile, _accept) Image.register_save(FitsImageFile.format, _save) # method given in docs #Image.register_open(FitsImageFile.format, FitsImageFile) Image.register_extension(FitsImageFile.format, ".fits") Image.register_extension(FitsImageFile.format, ".fit") # test code if __name__ == "__main__": import os fits_name = "fpC-001739-r1-0304.fit" jpg_name = os.path.splitext(fits_name)[0] + ".jpg" image = Image.open(fits_name).save(jpg_name) print "Converted FITs image '%s' to jpeg image '%s'" % (fits_name, jpg_name) -- http://mail.python.org/mailman/listinfo/python-list