-
Notifications
You must be signed in to change notification settings - Fork 10
/
dump_exif.py
78 lines (68 loc) · 2.98 KB
/
dump_exif.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
from __future__ import print_function
import PIL.Image
import PIL.ExifTags
import sys
import os
def formatted_exif_data(image):
"""Retrieve an image's EXIF data and return as a dictionary with string keys"""
# with thanks to https://stackoverflow.com/questions/4764932/in-python-how-do-i-read-the-exif-data-for-an-image
exif_data = {}
for k, v in image._getexif().items():
# Use names rather than codes where they are available
try:
exif_data[PIL.ExifTags.TAGS[k]] = v
except KeyError:
exif_data[k] = v
return exif_data
def parse_maker_note(maker_note):
"""Split the "maker note" EXIF field from a Raspberry Pi camera image into useful parameters"""
camera_parameters = {}
last_key = None
for p in maker_note.decode().split(" "):
# The maker note contains <thing>=<thing> entries, space delimited but with spaces in some values.
# So, if there is an = then we assume we've got key=value, but if there is no = sign, we append
# the current chunk to the latest value, because that's where it probably belongs...
if "=" in p:
last_key, v = p.split("=")
camera_parameters[last_key] = v
else:
camera_parameters[last_key] += " " + p
return camera_parameters
def print_kv(k, v, format=""):
"""Consistently print a key-value pair"""
print(kv_to_string(k, v, format=format))
def kv_to_string(k, v, format=""):
"""Consistently output a key-value pair as text"""
return ("{0: >28}: {1" + format + "}").format(k, v)
def exif_data_as_string(image):
"""Extract the EXIF data from a PIL image object, and format as a string."""
exif_data = formatted_exif_data(image)
output = ""
for k, v in exif_data.items():
output += kv_to_string(k, v) + "\n"
try:
camera_parameters = parse_maker_note(exif_data['MakerNote'])
output += "MakerNote Expanded:\n"
for k, v in camera_parameters.items():
output += kv_to_string(k, v) + "\n"
except:
print("Error decoding maker note - perhaps this JPEG wasn't made by picamera?")
try:
output += "Derived Values:\n"
# calculate exposure time - see https://www.media.mit.edu/pia/Research/deepview/exif.html
ssv = exif_data['ShutterSpeedValue']
exposure_time = 1/2.0**(float(ssv[0])/ssv[1])
output += kv_to_string("exposure_time", exposure_time, ":.4")
except:
print("No derived values - perhaps this JPEG wasn't made by picamera?")
return output
if __name__ == "__main__":
try:
assert len(sys.argv) == 2
assert os.path.isfile(sys.argv[1])
except:
print("Usage: {} <filename.jpg>".format(sys.argv[0]))
print("This tool will print out a summary of the image's metadata. It's designed to work with images taken on a Raspberry Pi camera.")
exit(-1)
image = PIL.Image.open(sys.argv[1])
print(exif_data_as_string(image))