HPI/my/photos/utils.py
2020-03-13 00:10:27 +00:00

86 lines
2.1 KiB
Python

from pathlib import Path
from typing import Dict
import PIL.Image # type: ignore
from PIL.ExifTags import TAGS, GPSTAGS # type: ignore
Exif = Dict
# TODO PIL.ExifTags.TAGS
class ExifTags:
DATETIME = "DateTimeOriginal"
LAT = "GPSLatitude"
LAT_REF = "GPSLatitudeRef"
LON = "GPSLongitude"
LON_REF = "GPSLongitudeRef"
GPSINFO = "GPSInfo"
# TODO there must be something more standard for this...
def get_exif_from_file(path: Path) -> Exif:
# TODO exception handler?
with PIL.Image.open(str(path)) as fo:
return get_exif_data(fo)
def get_exif_data(image):
"""Returns a dictionary from the exif data of an PIL Image item. Also converts the GPS Tags"""
exif_data = {}
info = image._getexif()
if info:
for tag, value in info.items():
decoded = TAGS.get(tag, tag)
if decoded == ExifTags.GPSINFO:
gps_data = {}
for t in value:
sub_decoded = GPSTAGS.get(t, t)
gps_data[sub_decoded] = value[t]
exif_data[decoded] = gps_data
else:
exif_data[decoded] = value
return exif_data
def to_degree(value):
"""Helper function to convert the GPS coordinates
stored in the EXIF to degress in float format"""
d0 = value[0][0]
d1 = value[0][1]
d = float(d0) / float(d1)
m0 = value[1][0]
m1 = value[1][1]
m = float(m0) / float(m1)
s0 = value[2][0]
s1 = value[2][1]
s = float(s0) / float(s1)
return d + (m / 60.0) + (s / 3600.0)
def convert_ref(cstr, ref: str):
val = to_degree(cstr)
if ref == 'S' or ref == 'W':
val = -val
return val
import re
from datetime import datetime
from typing import Optional
# TODO surely there is a library that does it??
_DT_REGEX = re.compile(r'\D(\d{8})\D*(\d{6})\D')
def dt_from_path(p: Path) -> Optional[datetime]:
name = p.stem
mm = _DT_REGEX.search(name)
if mm is None:
return None
dates = mm.group(1) + mm.group(2)
return datetime.strptime(dates, "%Y%m%d%H%M%S")