扩展PIL解码器
我有一个文件,这个文件里包含了一张特定格式的图片,而且这张图片在文件中的位置也是固定的。我已经能够获取到一个类似文件的对象,这个对象可以用来读取图片内容、移动读取位置和查看当前读取位置。我想利用一个现有的PIL解码器来处理这个嵌入的图片,但同时又希望能够把整个文件当作一个“图片文件”来使用。
不过,我一直没能搞清楚怎么做到这一点,尽管我查阅了相关文档,所以想问问有没有人能给我一些建议,告诉我该怎么做。
2 个回答
9
相关的文档章节可以在这里找到,我觉得讲得很清楚:比如说,如果你想解码新的.zap
格式的图片文件,你需要写一个叫ZapImagePlugin.py
的模块,这个模块需要完成几个事情:
- 要有一个
class ZapImageFile(ImageFile.ImageFile):
,里面要有字符串属性format
和format_description
,还要有一个钩子方法def _open(self)
(后面会详细讲); - 在模块的顶层,要执行
Image.register_open('zap', ZapImageFile)
和Image.register_extension('ZAP', '.zap')
。
关于_open
方法的具体要求在章节中讲得很清楚——它必须从打开的二进制文件对象self.fp
中读取图片数据和元数据,如果发现文件格式不对,必须尽快抛出SyntaxError
(或者其他异常),还要设置至少self.size
和self.mode
这两个属性。为了能读取这张图片,还需要设置self.tile
,这是一个包含瓦片描述符的列表,格式也是在那一章节中说明的(包括文件偏移量,你应该知道的,还有解码器——如果章节中提供的原始解码器或位解码器不符合你的需求,建议你去看看一些常见解码器的源代码,比如JPEG、PNG等)。
4
我解决这个问题的方法是,从嵌入格式的 ImageFile.ImageFile
子类派生,而不是直接使用 ImageFile.ImageFile
。然后在 _open()
方法里,我把 self.fp
替换成了指向嵌入图像的文件对象,并调用了父类的 _open()
方法。我不能说我特别喜欢这样做,但看起来这个方法是有效的。