Skip to content

Instantly share code, notes, and snippets.

@mipsparc mipsparc/pnginfo.py
Created Jan 5, 2015

Embed
What would you like to do?
PNGメタデータを簡単に表示するもの
#coding:utf-8
#Print some infomation of a PNG file
import struct
import datetime
import binascii
def crcChecker(data, crc):
computedCRC = binascii.crc32(data)
crc = struct.unpack('> I', crc)[0]
return crc == computedCRC
filename = input('Filename: ')
data = open(filename, 'rb').read()
if data[:8] != bytes((0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A)):
print('This is not a PNG file')
exit()
flag_len = 4
seek = 8
IDATCount = 0
CRCError = 0
while seek <= len(data):
body_len = struct.unpack('> I', data[seek:seek+flag_len])[0]
chunk_len = body_len + 8
chunkName, chunkData, CRC = struct.unpack('> 4s {}s 4s'.format(body_len),
data[seek+flag_len:seek+flag_len+chunk_len])
if not crcChecker(chunkName+chunkData, CRC):
CRCError += 1
print('Broken chunk')
enc = 'ASCII'
chunkName = str(chunkName, enc)
#chunk specific process
if chunkName == 'IDAT':
IDATCount += 1
else:
print('---{}'.format(chunkName))
if chunkName == 'IHDR':
width, height, depth, colourType, compress, filterType, adam7 = \
struct.unpack('> I I B B B B ?', chunkData)
print('size: {}x{}'.format(width, height))
print('depth: {}'.format(depth))
if colourType == 0:
colour = 'Gray'
elif colourType == 2:
colour = 'RGB'
elif colourType == 3:
colour = 'Palette'
elif colourType == 4:
colour = 'Gray + Alpha'
elif colourType == 6:
colour = 'RGB + Alpha'
print('colour: {}'.format(colour))
print('Adam7: {}'.format(adam7))
if chunkName == 'bKGD':
print('background colour')
if colourType in {0, 4}:
backGnd = struct.unpack('> H', chunkData)
print('Gray {}'.format(backGnd))
elif colourType in {2, 6}:
backGnd = struct.unpack('> H H H', chunkData)
print('R: {},G: {},B:{}'.format(*backGnd))
elif colourType == 3:
backGnd = struct.unpack('> B', chunkData)
print('PaletIndex: {}'.format(backGnd))
if chunkName == 'tIME':
timestamp = struct.unpack('> H B B B B B', chunkData)
print(datetime.datetime(*timestamp).isoformat())
if chunkName == 'pHYs':
ppuX, ppuY, spec = struct.unpack('> I I ?', chunkData)
if spec:
dpi = [round(i/100*2.54, 3) for i in (ppuX,ppuY)]
print('DPI: {}'.format(dpi))
if chunkName == 'gAMA':
gamma = struct.unpack('> I', chunkData)[0]/100000
print('gamma(file): {}, gamma(machine): {}'.format(
gamma, round(1/gamma, 4))
)
seek += flag_len + chunk_len
if chunkName == 'IEND':
print('---IDAT chunk: {}'.format(IDATCount))
print('---CRC Error: {}'.format(CRCError))
break
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.