Refactoring

This commit is contained in:
Nyymix 2023-02-02 20:37:45 +02:00
parent 3c4996a747
commit 5824771012

148
exif.py
View file

@ -1,85 +1,107 @@
import json import json
import logging
from datetime import datetime
import PIL.ExifTags import pytz
from PIL import Image, IptcImagePlugin, TiffImagePlugin from PIL import Image, IptcImagePlugin, TiffImagePlugin
logger = logging.getLogger(__name__)
""" Required exif values """
TAGS_EXIF = {
0x9003: "DateTimeOriginal",
0x829D: "FNumber",
0x829A: "ExposureTime",
0x8827: "ISOSpeedRatings",
0x9204: "ExposureBiasValue",
0x8822: "ExposureProgram",
0x9207: "MeteringMode",
0x920A: "FocalLength",
0xA405: "FocalLengthIn35mmFilm",
0x0110: "Model",
0xA434: "LensModel",
}
""" Required iptc values """
TAGS_IPTC = {
(2, 25): "Keywords",
(2, 55): "DateCreated",
(2, 60): "TimeCreated",
}
class Exif: class Exif:
def __init__(self, filename: str): def __init__(self, filename: str):
self.filename = filename self.filename = filename
self.exif = {} self._exif = {}
self._iptc = {}
self.data = {}
""" Open image file """
try: try:
self.img = Image.open(self.filename) with Image.open(self.filename) as self.img:
self.img.verify() self.img.verify()
self._readExif() except Exception:
self._readIptc() logger.exception('Could not open image: %s', self.filename)
except:
print("Error Couldn't open image: %s" % filename)
""" Read exif tags """
def _readExif(self): try:
img = self.img._getexif() self._exif = {
for (key, value) in img.items(): TAGS_EXIF[k]: v
if key in PIL.ExifTags.TAGS: for k, v in self.img._getexif().items()
if k in TAGS_EXIF
}
for (key, value) in self._exif.items():
if isinstance(value, TiffImagePlugin.IFDRational): if isinstance(value, TiffImagePlugin.IFDRational):
value = float(value) self.data[key] = float(value)
elif isinstance(value, tuple): elif isinstance(value, tuple):
value = tuple(float(t) if isinstance(t, TiffImagePlugin.IFDRational) else t for t in value) self.data[key] = tuple(float(t) if isinstance(t, TiffImagePlugin.IFDRational) else t for t in value)
elif isinstance(value, bytes): elif isinstance(value, bytes):
value = value.decode(errors="replace") self.data[key] = value.decode('utf-8')
self.exif[PIL.ExifTags.TAGS[key]] = value else:
return self.exif self.data[key] = value
except Exception:
logger.warning('Could not read exif metadata from: %s', self.filename)
def _readIptc(self): """ Read iptc tags """
iptcTAGS = { try:
(1, 90): 'CodedCharacterSet', self._iptc = {
(2, 0): 'RecordVersion', TAGS_IPTC[k]: v
(2, 5): 'ObjectName', for k, v in IptcImagePlugin.getiptcinfo(self.img).items()
(2, 25): 'Keywords', if k in TAGS_IPTC
(2, 55): 'DateCreated', }
(2, 60): 'TimeCreated', for (key, value) in self._iptc.items():
(2, 62): 'DigitizationDate', if isinstance(value, list):
(2, 63): 'DigitizationTime', self.data[key] = [x.decode('utf-8') for x in value]
(2, 80): 'Byline', else:
(2, 120): 'Caption', self.data[key] = value.decode('utf-8')
(2, 90): 'City', except Exception:
(2, 92): 'Sub location', logger.warning('Could not read iptc metadata from: %s', self.filename)
(2, 95): 'Province State',
(2, 100): 'Country Code',
(2, 101): 'Country Name',
}
img = IptcImagePlugin.getiptcinfo(self.img)
for (key, value) in img.items():
decoded = iptcTAGS.get(key, str(key))
if isinstance(value, list):
self.exif[decoded] = [x.decode('utf-8') for x in value]
else:
self.exif[decoded] = value.decode('utf-8')
return self.exif
def getValue(self, value): def datetimeoriginal(self, timezone='UTC'):
if value in self.exif.keys(): """ Return DateTimeOriginal with timezone """
return self.exif[value] if 'DateTimeOriginal' in self.data:
try:
return datetime.strptime(self.data['DateTimeOriginal'], "%Y:%m:%d %H:%M:%S").astimezone(pytz.timezone(timezone))
except ValueError as e:
logger.warning('Could not parse date from: %s', self.filename)
else: else:
return {} return datetime.now(pytz.timezone(timezone))
def getJson(self): def json(self):
return json.dumps(self.exif) """ Return exif data in json format """
return json.dumps(self.data)
def getDic(self): def keywords(self):
return self.exif """ Return Keywords list """
if 'Keywords' not in self.data:
return []
if type(self.data['Keywords']) == list:
return self.data['Keywords']
return [self.data['Keywords']]
def __str__(self): def __str__(self):
return self.filename return self.filename
xxx = Exif('./photo.jpg')
print(xxx.getJson())
print(xxx.getValue('Keywords'))
print(xxx.getValue('DateTimeOriginal'))
print(xxx.getDic())
print(xxx)