Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python2
- import os
- import qrtools
- import sys
- from PIL import Image
- __author__ = "Maki from _PRIME_"
- __version__ = "1.0"
- def analyseImage(path):
- '''
- Pre-process pass over the image to determine the mode (full or additive).
- Necessary as assessing single frames isn't reliable. Need to know the mode
- before processing all frames.
- @param path: path to GIF file
- @type path: C{GIF}
- @raise path: Check if the file exists
- @return: This function returns a dictionnary that contains the image files.
- '''
- try:
- im = Image.open(path)
- results = {
- 'size': im.size,
- 'mode': 'full',
- }
- try:
- while True:
- if im.tile:
- tile = im.tile[0]
- update_region = tile[1]
- update_region_dimensions = update_region[2:]
- if update_region_dimensions != im.size:
- results['mode'] = 'partial'
- break
- im.seek(im.tell() + 1)
- except EOFError:
- pass
- return results
- except IOError:
- print("Wrong file name")
- def processImage(path):
- '''
- Iterate the GIF, extracting each frame and decode qr code on
- each extracted file.
- @param path: Path to GIF file
- @type path: C{GIF}
- @raise path: Check the file type
- @raise path: Check for end of file
- @return: This function returns nothing, it just write
- each frame of the GIF as a PNG file on disk.
- '''
- try:
- mode = analyseImage(path)['mode']
- flag = []
- im = Image.open(path)
- i = 0
- p = im.getpalette()
- last_frame = im.convert('RGBA')
- try:
- while True:
- # You can uncomment the line below to get more verbosity
- # print("saving {0} ({1}) frame {2}, {3} {4}".format(path, mode, i, im.size, im.tile))
- # If the GIF uses local colour tables, each frame will
- # have its own palette.
- # If not, we need to apply the global palette to the new frame.
- if not im.getpalette():
- im.putpalette(p)
- new_frame = Image.new('RGBA', im.size)
- # Is this file a "partial"-mode GIF where frames
- # update a region of a different size to the entire image?
- # If so, we need to construct the new frame by pasting
- # it on top of the preceding frames.
- if mode == 'partial':
- new_frame.paste(last_frame)
- # Will set frame name, example : if toto.gif in
- # input then toto-0.png, toto-1.png etc...
- png_file = '%s-%d.png' % (''.join(os.path.basename(path).split('.')[:-1]), i)
- new_frame.paste(im, (0, 0), im.convert('RGBA'))
- new_frame.save(png_file, 'PNG')
- # QR Code decoder
- qr = qrtools.QR()
- qr.decode(png_file)
- flag.append(qr.data)
- print(''.join(flag))
- i += 1
- last_frame = new_frame
- im.seek(im.tell() + 1)
- except EOFError:
- pass
- except TypeError:
- print("Wrong file type")
- def cleanDir():
- '''
- Directory cleaner, this function will delete all png file in
- the current directory.
- '''
- filelist = [f for f in os.listdir(".") if f.endswith(".png")]
- for f in filelist:
- os.remove(f)
- def showHelp():
- print("\
- This script will split a GIF File in frames and decode the QR Code inside it. \n \
- Frames will be stored in the current folder as png files and delete with the cleanDir function.\n \
- \n \
- Usage: gif_qr.py <file.gif> \
- ")
- if __name__ == "__main__":
- if len(sys.argv) > 1:
- gif_file = sys.argv[1]
- processImage(gif_file)
- # Comment the function below to keep PNG file
- cleanDir()
- else:
- showHelp()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement