Skip to content

Instantly share code, notes, and snippets.

@bactisme
Created August 22, 2013 10:17
Show Gist options
  • Save bactisme/6305544 to your computer and use it in GitHub Desktop.
Save bactisme/6305544 to your computer and use it in GitHub Desktop.
Using PIL to extract geo (GPS) EXIF data. Extract position from a list of images containing EXIF information. Very poorly written :/
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from PIL import Image
from PIL.ExifTags import TAGS
from pprint import pprint
def get_exif(fn):
try:
ret = {}
i = Image.open(fn)
info = i._getexif()
for tag, value in info.items():
decoded = TAGS.get(tag, tag)
ret[decoded] = value
return ret
except:
return False
def gps_human_assembly(gps_info):
"""
{0: (2, 3, 0, 0),
1: 'N',
2: ((46, 1), (36, 1), (54774, 1000)),
3: 'E',
4: ((101, 1), (46, 1), (36258, 1000)),
5: 0,
6: (22442, 10),
7: ((1, 1), (19, 1), (38000, 1000)),
"""
lat = gps_info[2]
lon = gps_info[4]
lat = str(lat[0][0]) + "° " + str(lat[1][0]) + "' " + str(float(lat[2][0]) / lat[2][1]) + "\" " + gps_info[1]
lon = str(lon[0][0]) + "° " + str(lon[1][0]) + "' " + str(float(lon[2][0]) / lon[2][1]) + "\" " + gps_info[3]
return lat + ", " + lon
def gps_convert_ddmmss(d, m, s):
dec_min = (m*1.0 + (s/60.0))
ans = d*1.0 + (dec_min/60.0)
return ans
def gps_decimal_degrees(gps_info):
lat = gps_info[2]
lon = gps_info[4]
lat = gps_convert_ddmmss(lat[0][0], lat[1][0], float(lat[2][0]) / lat[2][1])
lon = gps_convert_ddmmss(lon[0][0], lon[1][0], float(lon[2][0]) / lon[2][1])
return (round(lat, 6), round(lon, 6))
def look_for_gps_data(fn, pix):
exif = get_exif(fn)
if 'GPSInfo' in exif:
gps_info = exif['GPSInfo']
d = exif['DateTime']
if 2 not in gps_info:
return False
#pprint(exif)
return (fn, gps_info, d, pix)
else:
return False
def loop_on_dir(path):
from os import walk
import os
f = []
for (dirpath, dirnames, filenames) in walk(path):
f.extend(filenames)
gps_data = []
for fn in f:
p = os.path.join(path,fn)
if get_exif(p):
data = look_for_gps_data(p, fn)
if data:
gps_data.append(data)
return gps_data
def convert_date(date):
r = date.split(' ')
return r[0].replace(':', '-')+"T"+r[1]+"Z"
def create_gpx(gpx_file, gps_data):
f = open(gpx_file, 'w')
f.write('<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>')
f.write('<?xml-stylesheet type="text/xsl" href="details.xsl"?>')
f.write("""
<gpx
version="1.0"
creator="Extract exif"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.topografix.com/GPX/1/0"
xmlns:topografix="http://www.topografix.com/GPX/Private/TopoGrafix/0/1" xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd http://www.topografix.com/GPX/Private/TopoGrafix/0/1 http://www.topografix.com/GPX/Private/TopoGrafix/0/1/topografix.xsd">
""")
for fn,px,date,pix in gps_data:
lat, lon = gps_decimal_degrees(px)
f.write('<wpt lat="' + str(lat) + '" lon="' + str(lon) + '">')
d = convert_date(date)
f.write('<time>' + d + '</time>')
f.write("<name><![CDATA[" + date + " - " + pix + "]]></name>")
f.write("<desc><![CDATA[" + pix + "]]></desc>")
f.write("<sym>Dot</sym>")
f.write("<type><![CDATA[Dot]]></type>")
f.write('<ele>100.0</ele>')
f.write('</wpt>')
f.write("</gpx>")
f.close()
# MAIN
gps_data = loop_on_dir("/Users/baptiste/dev/exifpython/img")
create_gpx("test_file.gpx", gps_data)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment