如何使用Python Image Library(PIL / Pillow)检测图像是否是渐进式JPEG?

时间:2014-11-07 09:21:31

标签: python python-imaging-library pillow

如果使用PIL或Photoshop等任何工具将图像保存为渐进式JPEG。 PIL或任何其他python模块中是否存在任何功能来检测输入图像文件是否是渐进式的?

3 个答案:

答案 0 :(得分:3)

根据this概念检查以下解决方案:

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))

解决方案不需要任何其他模块。

答案 1 :(得分:3)

不幸的是,Alderven的解决方案对我来说并不起作用,它认为一堆渐进式图像是非渐进式的。所以我实现了我自己的方法,它正确地实现了JPEG standard,并且应该适用于100%的文件(并且也不需要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

答案 2 :(得分:2)

图片有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}