Extract GPS coordinates from digital camera images using PHP
Article Metadata
Contents |
Introduction
The photos taken with digital cameras, mobile or otherwise, contain a lot of interesting information that is stored inside the image in a metadata format called EXIF (exchangeable image file) . This data makes each image unique. EXIF data contains information like, model of the camera, the aperture used, ISO level, and if the flash was used or not.
Amongst the information in the EXIF data will be geolocation; latitude and longitude of the place that the photo was initially shot. This information would be useful e.g. in conjunction with a mapping API to show the image on the actual geolocation over the world map. There are already online photo sharing communities e.g. Panoramio, locr or Flickr, which do allow uploading of geocoded images or to add geolocation information online.
Nokia has developed a series of mobile phones that are equipped with a GPS receiver and therefore able to tag all captured images with the location Note that on a mobile device that supports it, one has to remember to enable the GPS location feature in the Camera application setup.
The main objective of this article is to provide an example of how to extract the data in the digital camera image file, and place the data into an array, which can be then used further. The script is written in PHP and can run in a Windows / Linux environment, hosted either locally or remotely that is configured to support PHP. In the pre-requisites it is mentioned that the PHP needs to be configured to support reading the EXIF information. How to configure this, will be explained further in this wiki article. Please note that the PHP script in this Wiki article represents only basic functionality to perform the tasks.
Interaction with a WRT widget
- Note: This example is WRT development compatible, as you could join it with the multiple file to server upload example, found here: http://wiki.forum.nokia.com/index.php?title=Upload_multiple_files_to_a_webserver
Prerequisites
- a Nokia mobile device with GPS support
Note: Storing GPS info must have been enabled when taking images for using the PHP script. If the images do not contain location data, the script will inform the user and exit.
- Web server/hosting with full access rights to modify and edit files at web root level - Modify the php.ini file to enable the exif dynamic link library. Please see the instructions below:
Enabling PHP EXIF support on local server, in this example we have installed WAMP package. The message indicates that the EXIF extension has not been enabled.
Click open the [ Setup MySQL in WAMP - password setting, service shutdown & startup WAMPServer] menu on the right screen bottom corner and enable the php_exif parameter
in the list shown on the picture below.
You can also directly edit the PHP.ini file and uncomment the php_exif line in it.
extension=php_exif.dll
Note: You may need to put the following line enabled before the php_exif.dll to make this work:
extension=php_mbstring.dll
PHP script (server-side)
This script will read the GPS location data in each of the images fetched in function dirImages()
<?php
$dir = "./img";
function readGPSinfoEXIF($image_full_name)
{
$exif=exif_read_data($image_full_name, 0, true);
if(!$exif || $exif['GPS']['GPSLatitude'] == '') {
return false;
} else {
$lat_ref = $exif['GPS']['GPSLatitudeRef'];
$lat = $exif['GPS']['GPSLatitude'];
list($num, $dec) = explode('/', $lat[0]);
$lat_s = $num / $dec;
list($num, $dec) = explode('/', $lat[1]);
$lat_m = $num / $dec;
list($num, $dec) = explode('/', $lat[2]);
$lat_v = $num / $dec;
$lon_ref = $exif['GPS']['GPSLongitudeRef'];
$lon = $exif['GPS']['GPSLongitude'];
list($num, $dec) = explode('/', $lon[0]);
$lon_s = $num / $dec;
list($num, $dec) = explode('/', $lon[1]);
$lon_m = $num / $dec;
list($num, $dec) = explode('/', $lon[2]);
$lon_v = $num / $dec;
$gps_int = array($lat_s + $lat_m / 60.0 + $lat_v / 3600.0, $lon_s
+ $lon_m / 60.0 + $lon_v / 3600.0);
return $gps_int;
}
}
function dirImages($dir)
{
$d = dir($dir);
while (false!== ($file = $d->read()))
{
$extension = substr($file, strrpos($file, '.'));
if($extension == ".jpg" || $extension == ".jpeg" || $extension == ".gif"
|$extension == ".png")
$images[$file] = $file;
}
$d->close();
return $images;
}
$array = dirImages('./img');
$counter = 0;
foreach ($array as $key => $image)
{
echo "<br />";
$counter++;
echo $counter;
echo "<br />";
$image_full_name = $dir."/".$key;
echo $image_full_name;
$results = readGPSinfoEXIF($image_full_name);
$latitude = $results[0];
echo $latitude;
echo "<br />";
$longitude = $results[1];
echo $longitude;
echo "<br />";
}
?>
Example output
Example output for three (3) photos (latitude, longitude pairs). You may use these pairs to put e.g. a marker on the map.
1
./img/10052010062.jpg
60.183136759944
24.644625324111
2
./img/10052010063.jpg
60.18328319175
24.644759937444
3
./img/10052010064.jpg
60.183398694333
24.644894969833
Tested with
localhost & remote hosting
Development Environment
- Camera used : Nokia N97
- WAMP Server (localhost) running on a Windows XP Pro desktop
- Remote web service with Windows hosting




Mikesparr - missing a step in geo coordinates
You need to edit your exif function to add the minus sign on lat/lon if S or W orientation respectively. I updated your code example with the fix below so it works "across the pond"... ;-)
replace above function -----
function readGPSinfoEXIF($image_full_name) {
$exif=exif_read_data($image_full_name, 0, true); if(!$exif || $exif['GPS']['GPSLatitude'] == ) { return false; } else { $lat_ref = $exif['GPS']['GPSLatitudeRef']; $lat = $exif['GPS']['GPSLatitude']; list($num, $dec) = explode('/', $lat[0]); $lat_s = $num / $dec; list($num, $dec) = explode('/', $lat[1]); $lat_m = $num / $dec; list($num, $dec) = explode('/', $lat[2]); $lat_v = $num / $dec;$lon_ref = $exif['GPS']['GPSLongitudeRef']; $lon = $exif['GPS']['GPSLongitude']; list($num, $dec) = explode('/', $lon[0]); $lon_s = $num / $dec; list($num, $dec) = explode('/', $lon[1]); $lon_m = $num / $dec; list($num, $dec) = explode('/', $lon[2]); $lon_v = $num / $dec;$lat_int = ($lat_s + $lat_m / 60.0 + $lat_v / 3600.0); // check orientaiton of latitude and prefix with (-) if S $lat_int = ($lat_ref == "S") ? '-' . $lat_int : $lat_int;$lon_int = ($lon_s + $lon_m / 60.0 + $lon_v / 3600.0); // check orientation of longitude and prefix with (-) if W $lon_int = ($lon_ref == "W") ? '-' . $lon_int : $lon_int;$gps_int = array($lat_int, $lon_int); return $gps_int; }}mikesparr 21:39, 28 January 2012 (EET)
Reema89 -
$dir = "./exif"; //$image="image.jpg";
function readGPSinfoEXIF($image_full_name) {
$exif=exif_read_data($image_full_name, 0, true); if(!$exif || $exif['GPS']['GPSLatitude'] == ) { return false;} else { $lat_ref = $exif['GPS']['GPSLatitudeRef']; $lat = $exif['GPS']['GPSLatitude']; list($num, $dec) = explode('/', $lat[0]); $lat_s = $num / $dec; list($num, $dec) = explode('/', $lat[1]); $lat_m = $num / $dec; list($num, $dec) = explode('/', $lat[2]); $lat_v = $num / $dec;
$lon_ref = $exif['GPS']['GPSLongitudeRef']; $lon = $exif['GPS']['GPSLongitude']; list($num, $dec) = explode('/', $lon[0]); $lon_s = $num / $dec; list($num, $dec) = explode('/', $lon[1]); $lon_m = $num / $dec; list($num, $dec) = explode('/', $lon[2]); $lon_v = $num / $dec;
$gps_int = array($lat_s + $lat_m / 60.0 + $lat_v / 3600.0, $lon_s
return $gps_int; } }
function dirImages($dir) { $d = dir($dir); while (false!== ($file = $d->read())) { $extension = substr($file, strrpos($file, '.')); if($extension == ".jpg" || $extension == ".jpeg" || $extension == ".gif" |$extension == ".png")$images[$file] = $file; } $d->close(); return $images; } $array = dirImages('./exif'); $counter = 0;
foreach ($array as $key => $image) {
$counter++;
$image_full_name = $dir."/".$key; echo $image_full_name; $results = readGPSinfoEXIF($image_full_name); $latitude = $results[0]; echo $latitude;
$longitude = $results[1]; echo $longitude;
}
i used this php code i am getting warning Warning: dir(./exif,./exif) [function.dir]: The system cannot find the file specified. (code: 2) in C:\wamp\www\reema\self\exif\2.php on line 61
Fatal error: Call to a member function read() on a non-object in C:\wamp\www\reema\self\exif\2.php on line 62reema89 09:52, 18 February 2013 (EET)