For a project I am working on I had to quickly throw together a Python function to grab the width and height of JPEG files on disk. There is nothing in the python standard library to do this and although some third party projects that read JPEG files (micro-jpeg-visulaizer, PIL) they seem like overkill if all you want are the dimensions.
A quick trip to the JPEG standards document provided the information I needed. In case anyone else needs something similar, here is what I came up with:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
from struct import unpack def GetWidthAndHeight(stream): """ Extract the dimensions from a jpeg file as a tuple (width, height) Keyword arguments: stream -- a stream (eg: open()ed). Must be opened in binary mode Author: Andrew Stephens http://sandfly.net.nz/ License: use in any way you wish """ while (True): data = stream.read(2) marker, = unpack(">H", data) # some markers stand alone if (marker == 0xffd8): # start of image continue if (marker == 0xffd9): # end of image return; if ((marker >= 0xffd0) and (marker <= 0xffd7)): # restart markers continue if (marker == 0xff01): # private marker: continue # all other markers specify chunks with lengths data = stream.read(2) length, = unpack(">H", data) if (marker == 0xffc0): # baseline DCT chunk, has the info we want data = stream.read(5) t, height, width = unpack(">BHH", data) return (width, height) # not the chunk we want, skip it stream.seek(length - 2, 1)
This should be quicker than other solutions since it skips over parts of the stream it doesn’t need and is flexible enough to work on anything that looks like a seekable file. Beware, it may misbehave on malformed files.
Usage is simple:
1 2 3
f = open("somepicture.jpg", "rb") # need to open the stream in binary mode w, h = GetWidthAndHeight(f) f.close()