Tutorial #22
Using Metadata from Photographs Advanced   2013-11-18


The cameras that are integrated into smartphones today have led to an explosion in photography. While the quality and subject matter of much of this is questionable (just take a look at a typical facebook page...), this capability has changed the way we handle phographs.

The combination of phone cameras, GPS units and other sensors results in metadata for each photograph that can include the date and time it was taken, the location, the direction the camera was pointing, the exposure settings and much more.

Your applications can extract this metadata and use it to create timelines and display maps that are linked to the photos.

This tutorial shows how to extact image metadata from a photograph on the server and use it to create a map showing where it was taken.

Demo 1 screenshot for this tutorial

Step by Step

There are several formats for image metadata, but the most common appear to be EXIF, derived from the TIFF image format, and XMP from Adobe. In addition, there are many formats for encoding images. This would sound like a nightmare but thanks to the hard work of Phil Harvey we can use ExifTool which handles ALL of them !

ExifTool consists of an extensive library of Perl routines for reading, writing and manipulating metadata, along with a command line tool.

To access ExifTool from a Ruby application we can use the mini_exiftool gem from Jan Friedrich which calls the command line tool. However that won't work with an application hosted on Heroku, which is where I run this site. For that I use mini_exiftool_vendored from Wil Gieseler, which packages the ExifTool Perl libraries such that you don't need the command line tool.

The server code running this demo extracts the metadata for the image, selects the Latitude, Longitude and places these inside a JavaScript that renders a Google Map when the web page loads. It also generates a line on the map that marks the direction the camera was pointing when the photograph was taken.

Image 1 for this tutorial

Below these, is a dump of all the key: value attribute pairs that are available in the metadata. As well as GPS location data, these include the date and time the photo was taken, details about the camera that was used as well as information on the exposure and focus settings at which the picture was captured.

Image 2 for this tutorial

The photo in this demo was taken with an iPhone 4S. The metadata that is available from your phone or device may be different.

Understanding the Code

To set up your own working version of this demo you need to host it on a running server that is not localhost and you need to include a valid Google Maps APIkey for that site.

Add the line gem 'mini_exiftool_vendored' to your GemFile of your Ruby application and run bundle install. You can ignore the warning about installing the command line tool.

The code for this demo has 3 components.

To keep the tutorial relatively simple, I am using a test photo that I have placed on the demo site manually.

The first block of code is the server action - the code that extracts the metadata from the image file and reformats the latitude and longitude coordinates.

It also uses that location and the direction the camera was pointed to generate a second Lat/Lon coordinate pair which is set a short distance away from the first, along the path of that bearing. This will be used to draw a line on the map indicating the bearing.

The second component is a library of methods that are used in the demo. I have pulled these out into a separate file so as to keep the main Sinatra app file as clear as possible.

The first line of this loads the mini_exiftool_vendored gem, which includes the exiftoolPerl libraries.

The other methods manipulate latitude and longitude coordinates. dms_to_decimal converts deg, min, sec coordinate format into the decimal version that we need for Google Maps. latlong_offset creates a second Lat/Lon corrdinate pair that is a short distance away along the GPSImgDirection included in the metadata that represents the direction in which the camera was pointed when the image was taken. This will be used to draw a line on the map which shows that direction.

The third component is the view template that renders the web page containing the photograph, a map showing where it was taken and a dump of all the metadata contained in the original image file

This is an erb template, which is HTML that includes <% ... %> tag pairs which enclose Ruby code. These code blocks are evaluated and replaced with the result of that, just like PHP, etc.

The first section of this code block is HTML with an img tag for the photo and a div into which the map will be rendered. This is followed by a dump of all the metadata key: value pairs, which are referred to here as tags.

This is followed by style and script blocks that are similar to those introduced in Tutorial 15. What is new here are the definitions of lineCoordinates, symbols and a google.maps.Polyline. In our case we are only drawing one line, starting at the Lat/Lon where the photo was taken, along the direction it was taken, to a short distance away.

Even though the code here has several moving parts, it is not that difficult to code up if you are familiar with Sinatra or Rails applications, or their equivalents in Python, etc.

For me, being able to get time, location and direction information from photographs and use that in a web application is remarkable. I hope this tutorial helps get you started with the technology.

Code for this Tutorial

Share this tutorial

Related Tutorials

15 : Display a Google Map using JavaScript   (Intermediate)

19 : Geolocation in HTML5   (Intermediate)

Comment on this Tutorial

comments powered by Disqus