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:
- Photobucket - Strips EXIF
- Facebook - Strips EXIF
- Twitter - Strips EXIF
- Instagram - Strips EXIF
- Flickr - Strips EXIF
- Google+ - Preserves EXIF
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 NCoordinates 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
- ExifRead 2.1.2: pypi.python.org/pypi/ExifRead
- Jeffrey's EXIF Viewer: regex.info/exif.cgi
- ExifTool: www.sno.phy.queensu.ca/~phil/exiftool
- Google Maps: www.google.com/maps
- FCC Degrees, Minutes, Seconds: www.fcc.gov/media/radio/dms-decimal
- FileMind QuickFix: download.cnet.com/FileMind-QuickFix/3000-12511_4-75563232.html
Code: Listing1.py
Code: Listing2.py
Code: Listing3.py