扩展PIL解码器

14 投票
2 回答
1210 浏览
提问于 2025-04-15 19:14

我有一个文件,这个文件里包含了一张特定格式的图片,而且这张图片在文件中的位置也是固定的。我已经能够获取到一个类似文件的对象,这个对象可以用来读取图片内容、移动读取位置和查看当前读取位置。我想利用一个现有的PIL解码器来处理这个嵌入的图片,但同时又希望能够把整个文件当作一个“图片文件”来使用。

不过,我一直没能搞清楚怎么做到这一点,尽管我查阅了相关文档,所以想问问有没有人能给我一些建议,告诉我该怎么做。

2 个回答

9

相关的文档章节可以在这里找到,我觉得讲得很清楚:比如说,如果你想解码新的.zap格式的图片文件,你需要写一个叫ZapImagePlugin.py的模块,这个模块需要完成几个事情:

  • 要有一个class ZapImageFile(ImageFile.ImageFile):,里面要有字符串属性formatformat_description,还要有一个钩子方法def _open(self)(后面会详细讲);
  • 在模块的顶层,要执行Image.register_open('zap', ZapImageFile)Image.register_extension('ZAP', '.zap')

关于_open方法的具体要求在章节中讲得很清楚——它必须从打开的二进制文件对象self.fp中读取图片数据和元数据,如果发现文件格式不对,必须尽快抛出SyntaxError(或者其他异常),还要设置至少self.sizeself.mode这两个属性。为了能读取这张图片,还需要设置self.tile,这是一个包含瓦片描述符的列表,格式也是在那一章节中说明的(包括文件偏移量,你应该知道的,还有解码器——如果章节中提供的原始解码器或位解码器不符合你的需求,建议你去看看一些常见解码器的源代码,比如JPEG、PNG等)。

4

我解决这个问题的方法是,从嵌入格式的 ImageFile.ImageFile 子类派生,而不是直接使用 ImageFile.ImageFile。然后在 _open() 方法里,我把 self.fp 替换成了指向嵌入图像的文件对象,并调用了父类的 _open() 方法。我不能说我特别喜欢这样做,但看起来这个方法是有效的。

撰写回答