EXIF Location Recon with Python

by Michael L. Kelley, Jr.

Many photographs found on the web contain valuable information embedded inside.  This metadata, known as Exchangeable Image File Format (EXIF) is written to the image file by the device that it was captured with.  This can include: date and time, device information, camera settings, copyright information, and geographical location.

While useful, this EXIF data can lead to privacy concerns.  This article will discuss using the Python programming language to extract EXIF data from photographs and put the information to practical use.

I will be using Python 2.7.10 along with the ExifRead 2.1.2 package on a system running Windows 10.  Python can be downloaded at: www.python.org/downloads/

Once installed, set the PATH variable for Python under Windows: Control Panel > search 'Environment' > Edit Environment Variables

Edit the PATH to include:

C:\Python27; C:\Python27 Scripts\;

I used pip to install the ExifRead package.

For installing pip on Windows, see: stackoverflow.com/questions/4750806/how-to-install-pip-on-windows

Note:  Python 3 includes the pip package by default.

You will also want access to a few JPEG files that have EXIF metadata attached.  Any photo that you take with your phone or digital camera should have this data intact.

  Note:  Some websites strip out EXIF data upon upload.

As I've come to learn, this is a very controversial topic of debate as the data can be used for both ethical and non-ethical reasons.  Good examples would be capturing EXIF data to prove that a device was stolen or photographers using the data to try and recreate the exposure settings of a particular shot.  A bad example would be using the data to see where a person is at a particular time and then carry out a crime based on that information.

The following is a list of sites and their stances on EXIF data:

In Windows 10, you can verify if a photograph as EXIF data by right-clicking on the image file and choosing Properties > Details.  The properties and corresponding values will be listed.

Let us take a look at pulling EXIF tags under Python:

# Listing1.py
# Pull all EXIF Tags 
# pip install exifread

import exifread

f = open("C:\Users\Username\Desktop\Sample1.jpg") # Location of photograph 

tags = exifread.process_file(f)

for tag in tags.keys():
  if tag not in ('JPEGThumbnail', 'TIFFThumbnail', 'Filename', 'EXIF MakerNote'):
  	print("Key: %s, value %s" % (tag, tags[tag]))

Listing1.py will try and pull all of the EXIF metadata tags that it can find from a photograph.  What if we just want certain information like GPS?  Let's take a look at the next listing:

# Listing2.py
# Only GPS info
# pip install exifread

import exifread

f = open("C:\Users\Username\Desktop\Sample1.jpg") # Location of photograph 

tags = exifread.process_file(f)

for tag in tags.keys():
	# Look for GPS tags and print them
  	if "GPS" in tag:
  		print("Key: %s, value %s" % (tag, tags[tag]))

Listing2.py pulls only the GPS tags and values and displays them.  This will include the latitude and longitude that the photograph was taken at.  ExifRead returns these values in degrees, minutes, and seconds.

For final example, let us pull relevant information from the EXIF data if we wanted to try and get device information and GPS information:

# Listing3.py
# Custom/Important Tags
# pip install exifread

import exifread

f = open("C:\Users\Username\Desktop\Sample1.jpg") # Location of photograph 

tags = exifread.process_file(f)

# Only find/print desired tags
for tag in tags.keys():
	if 'EXIF DateTimeOriginal' in tag:
		print("Original Date & Time: %s" % (tags[tag]))
	else:
		if 'GPS GPSLatitudeRef' in tag:
		print("Latitude Reference: %s" % (tags[tag]))
		else:
			if 'GPS GPSLatitude' in tag:
			print("GPS Latitude: %s" % (tags[tag]))
			else:
				if 'GPS GPSLongitudeRef' in tag:
				print("Longitude Reference: %s" % (tags[tag]))
				else:
					if 'GPS GPSLongitude' in tag:
					print("GPS Longitude: %s" %(tags[tag]))
					else:
					  if 'Image Model' in tag:
					  print("Model: %s" %(tags[tag]))
					     else:
					       if 'Image Make' in tag
							     print("Make: %s" %(tags[tag]))

Listing3.py will print the relevant information that will place a device make/model with the location where the photo was taken.

An example data pull from an image might look like so:

GPSLongitude, value [80, 16, 711/20]
GPSLongitudeRef, value w
GPSLatitude, value [40, 9, 3301/100]
GPSLatitudeRef value N

Coordinates are given in degrees, minutes, and seconds.  Using the FCC site listed in the resources below, we can calculate the decimal form for longitude and latitude.  To calculate the seconds for longitude in the above example, take: 711/20 = 35.5

So degrees = 80, minutes = 16, seconds = 35.5 would give the longitude decimal value of 80.276528.

This could then be used in conjunction with Google Maps to map the location once the latitude is found.

Further research with this could include making a custom script to pull EXIF tags from multiple photographs at once and also writing the information to a .TXT file for later use.  Also, know that EXIF data can be easily removed from images to prevent this type of use either manually or by using a program like FileMind QuickFix, which is listed in the resources below.

Resources

Code: Listing1.py

Code: Listing2.py

Code: Listing3.py

Return to $2600 Index