Skip to content

Instantly share code, notes, and snippets.

@tenekev
Created September 8, 2024 11:04
Show Gist options
  • Save tenekev/52f5357e73786d9fcb5d951393655687 to your computer and use it in GitHub Desktop.
Save tenekev/52f5357e73786d9fcb5d951393655687 to your computer and use it in GitHub Desktop.
This a python function that takes in Piexif data and outputs a more readable and manageable JSON data. It's opinionated - it strips and replaces some fields as they are not needed.
import re, json
def exif_to_standard_json(exif_data):
"""
Input: Piexif file data.
Output: Json
Personal flavors:
byte to string values:
standardized_value = re.sub(r'\u0000|\u0001|\u0002|\u0003', '', standardized_value)
standardized_value = re.sub(r' {2,}', '', standardized_value)
individual tags:
standardized_data['0th']['PrintImageMatching'] = None
standardized_data['0th']['PrintImageMatching'] = None
standardized_data['Exif']['MakerNote'] = None
standardized_data['Exif']['UserComment'] = None
standardized_data['thumbnail'] = None
"""
standardized_data = {}
# Ensure exif_data is a dictionary
if not isinstance(exif_data, dict):
raise ValueError("The provided EXIF data is not a valid dictionary.")
for ifd_name in exif_data:
# Ensure ifd_name data is also a dictionary, as expected
if isinstance(exif_data[ifd_name], dict):
standardized_data[ifd_name] = {}
for tag, value in exif_data[ifd_name].items():
tag_name = piexif.TAGS[ifd_name][tag]["name"]
# Convert values based on their type
if isinstance(value, bytes):
try:
# Try decoding bytes to string
standardized_value = value.decode('utf-8')
standardized_value = re.sub(r'\u0000|\u0001|\u0002|\u0003', '', standardized_value)
standardized_value = re.sub(r' {2,}', '', standardized_value)
except UnicodeDecodeError as e:
# If decoding fails, store raw bytes as a string representation
standardized_value = str(value)
elif isinstance(value, (int, float)):
standardized_value = value
elif isinstance(value, tuple):
# Handle tuples (e.g., rational numbers) appropriately
standardized_value = str(value)
else:
# Default to string representation for other types
standardized_value = str(value)
standardized_data[ifd_name][tag_name] = standardized_value
else:
# Handle non-dictionary cases (which may be `bytes` or other unexpected types)
standardized_data[ifd_name] = str(exif_data[ifd_name])
try: standardized_data['0th']['PrintImageMatching'] = None
except: pass
try: standardized_data['0th']['PrintImageMatching'] = None
except: pass
try: standardized_data['Exif']['MakerNote'] = None
except: pass
try: standardized_data['Exif']['UserComment'] = None
except: pass
try: standardized_data['thumbnail'] = None
except: pass
return standardized_data
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment