Here is my solution just in case someone is interested…
path = [PATH TO IMAGE FILE]
max_width = 520
max_height = 600
# see https://bugs.python.org/issue16512#msg198034
# not added to imghdr.tests because of potential issues with reloads
def _is_jpg(h):
return h.startswith(b'\xff\xd8')
# from http://stackoverflow.com/a/20380514/5963435
# somewhat enhanced from http://stackoverflow.com/a/39778771
def get_image_size(image_path):
'''Determine the image type of image_path and return its size.'''
with open(image_path, 'rb') as fhandle:
# read 32 as we pass this to imghdr
head = fhandle.read(32)
if len(head) != 32:
return
what = imghdr.what(image_path, head)
if what == 'png':
check = struct.unpack('>i', head[4:8])[0]
if check != 0x0d0a1a0a:
return
width, height = struct.unpack('>ii', head[16:24])
elif what == 'gif':
width, height = struct.unpack('<HH', head[6:10])
elif what == 'jpeg' or _is_jpg(head):
try:
fhandle.seek(0) # Read 0xff next
size = 2
ftype = 0
while not 0xc0 <= ftype <= 0xcf or ftype in (0xc4, 0xc8, 0xcc):
fhandle.seek(size, 1)
byte = fhandle.read(1)
while ord(byte) == 0xff:
byte = fhandle.read(1)
ftype = ord(byte)
size = struct.unpack('>H', fhandle.read(2))[0] - 2
# We are at a SOFn block
fhandle.seek(1, 1) # Skip `precision' byte.
height, width = struct.unpack('>HH', fhandle.read(4))
except Exception: # IGNORE:W0703
return
else:
return
return width, height
def image_scale(width, height, max_width, max_height):
resize_ratio = min(max_width/width, max_height/height)
if resize_ratio > 1:
return width, height
return round(width * resize_ratio), round(height * resize_ratio)
image_size = get_image_size(path)
image_size = image_scale(image_size[0], image_size[1], max_width= max_width, max_height= max_height)
content = '<img src="file:/%s" width="%s" height="%s">' % (path, image_size[0], image_size[1])
view.show_popup(content, max_width= max_width * 1.03, max_height= max_height * 1.03, location=point)