UWColorKit / exif_gps.py
budzynski's picture
Hugging face demo v1
4247de9
Raw
History Blame Contribute Delete
1.93 kB
"""Local EXIF GPS extraction to prefill the map pin (no pixels touched)."""
from typing import Optional, Tuple
def _to_degrees(tag):
try:
d, m, s = (float(p.num) / float(p.den) for p in tag.values)
return d + m / 60.0 + s / 3600.0
except (AttributeError, TypeError, ValueError, ZeroDivisionError):
return None
def extract_gps(path) -> Optional[Tuple[float, float]]:
try:
import exifread
except ImportError:
return None
try:
with open(path, "rb") as fh:
tags = exifread.process_file(fh, details=False)
except Exception:
return None
lat = _to_degrees(tags.get("GPS GPSLatitude"))
lng = _to_degrees(tags.get("GPS GPSLongitude"))
if lat is None or lng is None:
return None
if str(tags.get("GPS GPSLatitudeRef", "N")).strip().upper().startswith("S"):
lat = -lat
if str(tags.get("GPS GPSLongitudeRef", "E")).strip().upper().startswith("W"):
lng = -lng
if not (-90 <= lat <= 90 and -180 <= lng <= 180):
return None
return (lat, lng)
def extract_month(path) -> Optional[int]:
"""Calendar month (1-12) from the EXIF capture date, or None."""
try:
import exifread
except ImportError:
return None
try:
with open(path, "rb") as fh:
tags = exifread.process_file(fh, details=False)
except Exception:
return None
for key in ("EXIF DateTimeOriginal", "EXIF DateTimeDigitized", "Image DateTime"):
raw = str(tags.get(key, "")).strip()
if not raw:
continue
date_part = raw.split()[0] # "YYYY:MM:DD" or "YYYY-MM-DD"
bits = date_part.replace("-", ":").split(":")
if len(bits) >= 2:
try:
month = int(bits[1])
except ValueError:
continue
if 1 <= month <= 12:
return month
return None