Created
August 22, 2013 10:17
-
-
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 :/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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