Finding the Dimensions of a JPEG file in Python

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()