如何使用Python图像库(PIL/PILL)检测图像是否为渐进式JPEG?
如果图像已使用PIL或任何类似Photoshop的工具保存为渐进式JPEG。如何使用Python图像库(PIL/PILL)检测图像是否为渐进式JPEG?,python,python-imaging-library,pillow,Python,Python Imaging Library,Pillow,如果图像已使用PIL或任何类似Photoshop的工具保存为渐进式JPEG。 PIL或任何其他python模块中是否存在任何功能来检测输入图像文件是否是渐进的?根据概念检查以下解决方案: image = 'c:\\images\\progressive.jpg' def IsImageProgressive(image): previousXFF = False with open(image, "rb") as f: byte = f.read(1)
PIL或任何其他python模块中是否存在任何功能来检测输入图像文件是否是渐进的?根据概念检查以下解决方案:
image = 'c:\\images\\progressive.jpg'
def IsImageProgressive(image):
previousXFF = False
with open(image, "rb") as f:
byte = f.read(1)
while byte:
byte = f.read(1)
if previousXFF:
if 'xc2' in str(byte):
return True
if 'xff' in str(byte):
previousXFF = True
else:
previousXFF = False
return False
print(IsImageProgressive(image))
该解决方案不需要任何附加模块。有图像的
info
属性
In [1]: from PIL import Image
In [2]: Image.open('ex1.p.jpg').info
Out[2]:
{'jfif': 257,
'jfif_density': (1, 1),
'jfif_unit': 0,
'jfif_version': (1, 1),
'progression': 1,
'progressive': 1}
不幸的是,Alderven的解决方案不适用于我,它将一堆渐进式压缩图像识别为非渐进式。因此,我实现了我自己的方法,该方法正确地实现并应适用于100%的文件(也不需要PIL):
def IsImageProgressive(文件名):
打开(文件名为“rb”)作为f:
尽管如此:
blockStart=struct.unpack('B',f.read(1))[0]
如果阻止启动!=0xff:
raise VALUERROR('无效字符代码'+`blockStart`+'-不是JPEG文件:'+文件名)
返回错误
blockType=struct.unpack('B',f.read(1))[0]
如果blockType==0xd8:#图像的开始
持续
elif blockType==0xc0:#基线帧的开始
返回错误
elif blockType==0xc2:#递增帧的开始
返回真值
elif blockType>=0xd0和blockType
def IsImageProgressive(filename):
with open(filename, "rb") as f:
while True:
blockStart = struct.unpack('B', f.read(1))[0]
if blockStart != 0xff:
raise ValueError('Invalid char code ' + `blockStart` + ' - not a JPEG file: ' + filename)
return False
blockType = struct.unpack('B', f.read(1))[0]
if blockType == 0xd8: # Start Of Image
continue
elif blockType == 0xc0: # Start of baseline frame
return False
elif blockType == 0xc2: # Start of progressive frame
return True
elif blockType >= 0xd0 and blockType <= 0xd7: # Restart
continue
elif blockType == 0xd9: # End Of Image
break
else: # Variable-size block, just skip it
blockSize = struct.unpack('2B', f.read(2))
blockSize = blockSize[0] * 256 + blockSize[1] - 2
f.seek(blockSize, 1)
return False