Reputation: 43235
If an image has been saved as progressive JPEG using PIL or any tool like Photoshop. Is there any functionality present in PIL or any other python modules to detect if an input image file is progressive ?
Upvotes: 2
Views: 1904
Reputation: 528
Alderven's solution unfortunately didn't work for me, it recognized bunch of progressive-packed images as non-progressive. So I implemented my own method which properly implements JPEG standard and should work for 100% of files (and also doesn't need PIL):
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
Upvotes: 4
Reputation: 2252
There is info
property of image.
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}
Upvotes: 3
Reputation: 8270
Check following solution based on this conception:
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))
The solution requires no any additional modules.
Upvotes: 3