使用Python (PIL)读取有损坏头部的JPEG
我正在尝试在Python 2.7中打开一个jpeg文件,
from PIL import Image
im = Image.open(filename)
但是这对我来说没用,
>>> im = Image.open(filename)
Traceback (most recent call last):
File "<pyshell#810>", line 1, in <module>
im = Image.open(filename)
File "/usr/lib/python2.7/dist-packages/PIL/Image.py", line 1980, in open
raise IOError("cannot identify image file")
IOError: cannot identify image file
不过在其他查看器上试的时候,它打开得很好。深入研究后发现,PIL
的JpegImagePlugin.py
文件中的JpegImageFile._open
方法因为JPEG文件头中在0xFFDA
标记之前有几个多余的0x00
字节而引发了SyntaxError
异常,
Corrupt JPEG data: 5 extraneous bytes before marker 0xda
也就是说,虽然我尝试的其他程序只是忽略了文件头末尾的未知0x00
标记,但PIL
选择抛出异常,这让我无法打开这个图片。
问题:除了直接编辑PIL
的代码,还有什么方法可以打开有问题的JPEG文件吗?
下面是引发异常的JpegImageFile
类的相关代码,供你参考:
def _open(self):
s = self.fp.read(1)
if ord(s[0]) != 255:
raise SyntaxError("not a JPEG file")
# Create attributes
self.bits = self.layers = 0
# JPEG specifics (internal)
self.layer = []
self.huffman_dc = {}
self.huffman_ac = {}
self.quantization = {}
self.app = {} # compatibility
self.applist = []
self.icclist = []
while 1:
s = s + self.fp.read(1)
i = i16(s)
if MARKER.has_key(i):
name, description, handler = MARKER[i]
# print hex(i), name, description
if handler is not None:
handler(self, i)
if i == 0xFFDA: # start of scan
rawmode = self.mode
if self.mode == "CMYK":
rawmode = "CMYK;I" # assume adobe conventions
self.tile = [("jpeg", (0,0) + self.size, 0, (rawmode, ""))]
# self.__offset = self.fp.tell()
break
s = self.fp.read(1)
elif i == 0 or i == 65535:
# padded marker or junk; move on
s = "\xff"
else:
raise SyntaxError("no marker found")
1 个回答
5
PIL(Python Imaging Library)对损坏的文件头数据很敏感,正如你发现的那样,它会出现问题。
我已经向Pillow(PIL的一个友好的分支)提交了一个请求,希望能解决这个问题。
这个请求还没有被接受,但希望在几个月后即将发布的2.5.0版本中能包含这个修复。在此期间,你可以在这里试用一下:https://github.com/python-imaging/Pillow/pull/647
作为一个临时解决办法,你可以先用ImageMagick把有问题的图片转换成png格式,然后再在PIL/Pillow中使用它们。