Leer y Editar Metadatos EXIF de Imágenes con Python
Los metadatos EXIF almacenan información sobre cómo se tomó una foto: cámara, fecha, GPS, exposición y más. Python permite leerlos, modificarlos y eliminarlos con Pillow y piexif.
Instalación
pip install pillow piexif
Leer Metadatos EXIF
from PIL import Image
from PIL.ExifTags import TAGS
def leer_exif(ruta_imagen):
img = Image.open(ruta_imagen)
exif = img._getexif()
if not exif:
print("Sin metadatos EXIF")
return {}
datos = {}
for tag_id, valor in exif.items():
tag = TAGS.get(tag_id, tag_id)
datos[tag] = valor
print(f" {tag:30}: {str(valor)[:80]}")
return datos
leer_exif("foto_camara.jpg")
Leer GPS (Coordenadas de Ubicación)
from PIL import Image
from PIL.ExifTags import TAGS, GPSTAGS
def obtener_gps(ruta_imagen):
img = Image.open(ruta_imagen)
exif = img._getexif()
if not exif: return None
gps_info = {}
for tag_id, valor in exif.items():
tag = TAGS.get(tag_id, tag_id)
if tag == "GPSInfo":
for gps_tag_id, gps_valor in valor.items():
gps_tag = GPSTAGS.get(gps_tag_id, gps_tag_id)
gps_info[gps_tag] = gps_valor
def a_decimal(coords, ref):
grados, minutos, segundos = coords
decimal = grados + minutos/60 + segundos/3600
if ref in ['S', 'W']: decimal = -decimal
return round(decimal, 6)
if 'GPSLatitude' in gps_info:
lat = a_decimal(gps_info['GPSLatitude'], gps_info.get('GPSLatitudeRef', 'N'))
lon = a_decimal(gps_info['GPSLongitude'], gps_info.get('GPSLongitudeRef', 'E'))
print(f"Ubicación: {lat}, {lon}")
print(f"Google Maps: https://maps.google.com/?q={lat},{lon}")
return lat, lon
print("Sin datos GPS")
return None
obtener_gps("foto_viaje.jpg")
Modificar Metadatos EXIF
import piexif
from PIL import Image
def editar_exif(entrada, salida, autor=None, descripcion=None, fecha=None):
img = Image.open(entrada)
exif_raw = img.info.get("exif", b"")
try:
exif_dict = piexif.load(exif_raw) if exif_raw else {"0th":{}, "Exif":{}, "GPS":{}, "1st":{}}
except:
exif_dict = {"0th":{}, "Exif":{}, "GPS":{}, "1st":{}}
if autor:
exif_dict["0th"][piexif.ImageIFD.Artist] = autor.encode('utf-8')
if descripcion:
exif_dict["0th"][piexif.ImageIFD.ImageDescription] = descripcion.encode('utf-8')
if fecha:
# Formato: "YYYY:MM:DD HH:MM:SS"
exif_dict["0th"][piexif.ImageIFD.DateTime] = fecha.encode('utf-8')
exif_dict["Exif"][piexif.ExifIFD.DateTimeOriginal] = fecha.encode('utf-8')
exif_bytes = piexif.dump(exif_dict)
img.save(salida, exif=exif_bytes)
print(f"EXIF actualizado: {salida}")
editar_exif(
"foto.jpg", "foto_firmada.jpg",
autor="Pablo Fotografía",
descripcion="Paisaje de montaña al atardecer",
fecha="2024:06:15 18:30:00"
)
Eliminar Metadatos (Privacidad)
from PIL import Image
import piexif
def quitar_exif(entrada, salida):
img = Image.open(entrada)
# Método 1: Guardar sin EXIF
data = list(img.getdata())
img_sin_exif = Image.new(img.mode, img.size)
img_sin_exif.putdata(data)
img_sin_exif.save(salida)
print(f"EXIF eliminado: {salida}")
def quitar_exif_lote(carpeta, destino):
import os
from pathlib import Path
Path(destino).mkdir(exist_ok=True)
for nombre in os.listdir(carpeta):
if nombre.lower().endswith(('.jpg', '.jpeg')):
quitar_exif(
os.path.join(carpeta, nombre),
os.path.join(destino, nombre)
)
print(f" Limpiado: {nombre}")
quitar_exif("foto_original.jpg", "foto_privada.jpg")
quitar_exif_lote("fotos_originales/", "fotos_limpias/")
Añadir Coordenadas GPS a una Foto
import piexif
from PIL import Image
def anadir_gps(entrada, salida, latitud, longitud):
img = Image.open(entrada)
exif_raw = img.info.get("exif", b"")
try:
exif_dict = piexif.load(exif_raw)
except:
exif_dict = {"0th":{}, "Exif":{}, "GPS":{}, "1st":{}}
def a_racional(valor):
valor = abs(valor)
grados = int(valor)
minutos = int((valor - grados) * 60)
segundos = round(((valor - grados) * 60 - minutos) * 60 * 1000)
return [(grados,1), (minutos,1), (segundos,1000)]
exif_dict["GPS"][piexif.GPSIFD.GPSLatitudeRef] = b'N' if latitud >= 0 else b'S'
exif_dict["GPS"][piexif.GPSIFD.GPSLatitude] = a_racional(latitud)
exif_dict["GPS"][piexif.GPSIFD.GPSLongitudeRef] = b'E' if longitud >= 0 else b'W'
exif_dict["GPS"][piexif.GPSIFD.GPSLongitude] = a_racional(longitud)
img.save(salida, exif=piexif.dump(exif_dict))
print(f"GPS añadido: {latitud}, {longitud} -> {salida}")
# Madrid, España
anadir_gps("foto.jpg", "foto_geolocal.jpg", 40.4168, -3.7038)
Recurso Adicional
Para convertir imágenes entre JPG, PNG, WebP y otros formatos sin instalar nada, usa KaijuConverter — gratis y sin registro.
Conversiones relacionadas
Lo más habitual al trabajar con imágenes son estas direcciones de conversión: