Los metadatos EXIF de una fotografía contienen mucha información relativa a la misma, generalmente no somos conscientes de dicha información y no la utilizamos correctamente o la distribuimos de forma inconsciente al ir incluidos junto a la imagen en un único archivo.

Al realizar una foto, el dispositivo guarda información entre otros del tiempo de exposición, flash utilizado, modelo de cámara o teléfono movil, lugar exacto donde se realiza o fecha y hora.

Con dichos datos es posible ubicar nuestro domicilio, trazar un mapa de nuestras vacaciones, lugares más visitados, dispositivos móviles y cámaras, etc.

De cara a nuestra privacidad es importante conocer la existencia de esta información y cómo tratarla, por ejemplo eliminar estos datos antes de subir la foto a una red social.

{272: 'E6653', 305: '32.2.A.0.224_0_f500', 274: 6, 306: '2016:06:21 20:12:51', 'Flash': 16, 'FocalLength': (423, 100), 'ColorSpace': 1, 'ExifImageWidth': 3840, 'ExifInteroperabilityOffset': 20960, 'SceneCaptureType': 0, 'SubjectDistanceRange': 0, 'SubsecTime': '251832', 'SubsecTimeOriginal': '251832', 'SubsecTimeDigitized': '251832', 'ExifImageHeight': 2160, 'ExposureTime': (10, 200), 'FNumber': (20, 10), 'CustomRendered': 0, 'ISOSpeedRatings': 800, 'ExposureMode': 0, 'WhiteBalance': 0, 'DigitalZoomRatio': (100, 100), 'MakerNote': b'SONY MOBILE\x00\t\x...

Aunque cada metadato tiene su importancia, sin duda uno de los más utilizados y delicados de cara a nuestra privacidad es la ubicación, guardada con los datos GPS:

'GPSInfo': {'GPSVersionID': b'\x02\x02\x00\x00', 'GPSLatitudeRef': 'N', 'GPSLatitude': ((37, 1), (22, 1), (47866, 1000)), 'GPSLongitudeRef': 'W', 'GPSLongitude': ((6, 1), (2, 1), (9997, 1000)), 'GPSAltitudeRef': b'\x00', 'GPSAltitude': (94000, 1000), 'GPSTimeStamp': ((18, 1), (12, 1), (47000, 1000)), 'GPSStatus': 'A', 'GPSMapDatum': 'WGS-84', 'GPSDateStamp': '2016:06:21', 'Latitude': 37.37986277777778, 'Longitude': -6.0361152777777775}

Librerías

Las librerias utilizadas son viejas conocidas:

from PIL import Image
from PIL.ExifTags import TAGS, GPSTAGS

Código Python listar metadatos

Comencemos con un ejemplo simple, mostrar los metadatos EXIF por Terminal.

La siguiente función abre la imagen e imprime por pantalla los tags que va encontrando:

def exif_print(filename):
	try:
		image = Image.open(filename)
		exif = image._getexif().items()
		if exif is not None:
			for key, value in exif:
				svalue=str(value)[0:200]
				print("%s: %s" % (TAGS.get(key, key), svalue))
	except:
		debug.print_exception()
		return None

Para llamar a la función:

exif_print(<tu_archivo_de_imagen>)

En caso de error, para obtener mas información llamamos a print_exception(), puedes ver el detalle de esta función para tratar excepciones en esta entrada:

Si ejecutas desde Terminal obtendrás por pantalla algo parecido a esto:

GPSInfo: {0: b'\x02\x02\x00\x00', 1: 'N', 2: ((37, 1), (22, 1), (47816, 1000)), 3: 'W', 4: ((6, 1), (2, 1), (
ResolutionUnit: 2
ExifOffset: 214
Make: Sony
Model: E6653
Software: 32.2.A.0.224_0_f500
Orientation: 6
DateTime: 2016:06:21 20:10:35
YCbCrPositioning: 1
XResolution: (72, 1)
YResolution: (72, 1)
ExifVersion: b'0220'
ComponentsConfiguration: b'\x01\x02\x03\x00'
ShutterSpeedValue: (500, 100)
DateTimeOriginal: 2016:06:21 20:10:35
DateTimeDigitized: 2016:06:21 20:10:35
ExposureBiasValue: (0, 3)
FlashPixVersion: b'0100'
MeteringMode: 5
LightSource: 0
Flash: 16
FocalLength: (423, 100)
ColorSpace: 1
ExifImageWidth: 3840
ExifInteroperabilityOffset: 20960
SceneCaptureType: 0
SubjectDistanceRange: 0
SubsecTime: 056145
SubsecTimeOriginal: 056145
SubsecTimeDigitized: 056145
ExifImageHeight: 2160
ExposureTime: (10, 320)
FNumber: (20, 10)
CustomRendered: 0
ISOSpeedRatings: 125
ExposureMode: 0
WhiteBalance: 0
DigitalZoomRatio: (100, 100)
MakerNote: b'SONY MOBILE\x00\t\x00\x0f \x04\x00\x01\x00\x00\x00\x00

¿Interesante verdad?

Habrás visto la etiqueta GPSInfo, esta es la que nos interesa por ahora ya que contiene información relativa a las coordenadas GPS del momento de la captura.

Código Python extraer coordenadas GPS desde EXIF

El siguiente código recupera los datos EXIF y una vez obtenidos localiza coordenadas GPS para su tratamiento.

Declaramos dos funciones:

  • get_exif(archivo): recupera los metadatos EXIF en bruto
  • get_decimal_coordinates(info): devuelve coordenadas GPS: latitud y longitud
def get_decimal_coordinates(info):
	try:
		for key in ['Latitude', 'Longitude']:
			if 'GPS'+key in info and 'GPS'+key+'Ref' in info:
				e = info['GPS'+key]
				ref = info['GPS'+key+'Ref']
				info[key] = ( e[0][0]/e[0][1] + e[1][0]/e[1][1] / 60 + e[2][0]/e[2][1] / 3600) * (-1 if ref in ['S','W'] else 1)
		if 'Latitude' in info and 'Longitude' in info:
			return [float(info['Latitude']), float(info['Longitude'])]
		else:
			return [0.0, 0.0]
	except:		
		debug.print_exception()
		return None

def get_exif(filename):
	try:
		exif = Image.open(filename)._getexif()	
		if exif is not None:
			for key, value in exif.items():
				name = TAGS.get(key, key)
				exif[name] = exif.pop(key)
	
			if 'GPSInfo' in exif:
				for key in exif['GPSInfo'].keys():
					name = GPSTAGS.get(key,key)
					exif['GPSInfo'][name] = exif['GPSInfo'].pop(key)

		return exif
	    
	except:		
		debug.print_exception()
		return None

Para recuperar las coordenadas simplemente obtenemos los metadatos EXIF y posteriormente llamamos a la función get_decimal_coordinates() para las coordenadas:

sfilepath="/media/lubuntu/4A5B-42E5/cmrep/201606/20160621201251_efbbd74f15d4d1b8f3ca081f8af7b7f4.jpg"		
exif=get_exif(sfilepath)		
lat,lon=get_decimal_coordinates(exif['GPSInfo'])
print("%s %s" % (lat,lon))

Y listo! sencillo y práctico.

Si además de coordenadas, quieres ver como obtener la dirección en formato calle + ciudad + pais, te puede interesar esta entrada:

Dudas y comentarios donde siempre.

Saludos!

2 comentarios sobre «Python – datos EXIF – obtener coordenadas GPS de una fotografía»

  1. Nancy López

    Hola, buen día, probé tu código y me muestra la información de la foto, donde se ven los datos de GPS, pero cuando uso la función que me obtiene la información de GPS me devuelve 0.0 0.0

    1. admin

      Hola Nancy,
      es posible que el GPS estuviera inactivo al hacer la foto o que fuera tomada con un dispositivo sin GPS.

Deja tu comentario