skip to Main Content

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 ?

3

Answers


  1. 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.

    Login or Signup to reply.
  2. 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}
    
    Login or Signup to reply.
  3. 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
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search