@@ -127,13 +127,12 @@ def processExifSegment(info, segment) :
127127 continueLooking = True
128128 while (continueLooking ) :
129129 newIFDinfo = []
130- for knownIFDname , d in dict .items () :
130+ for d in dict .values () :
131131 for embeddedIFDtag , embeddedIFDname in knownEmbeddedIFDs ().items () :
132132 # This will re-search all IFDs each time through the loop, not just ones we've added last time
133133 # around, so ignore embedded IFDs we've already picked up. (Assuming the only exist in one place.)
134134 if embeddedIFDtag in d and embeddedIFDname not in dict :
135135 IFDname = embeddedIFDname
136- #print("Handling embedded IFD:", IFDname)
137136 embeddedIFDOffset = d [embeddedIFDtag ]['value' ]
138137 embeddedIFDentries , nextIFDOffset = processIFD (TIFF , embeddedIFDOffset , byteAlignmentIndicator )
139138 # Put info about embedded IFD onto a list, we can't put it directly in the main dictionary
@@ -475,9 +474,10 @@ def latLongAsStringNumber(NSEW, latLongTuples) :
475474 n = (degrees + (minutes / 60.0 ) + (seconds / 60.0 / 60.0 ) ) * multiplier
476475 return (s ,n )
477476
478- def summariseTags (allTags ) :
477+ def summariseTags (propertiesDict , allTags , verbose ) :
479478
480- print ()
479+ if verbose :
480+ print ()
481481
482482 # Where was the image (photo) produced ?
483483 if 'GPS' in allTags :
@@ -507,19 +507,25 @@ def summariseTags(allTags) :
507507
508508 if NS and latitude and EW and longitude :
509509 sLatitude , nLatitude = latLongAsStringNumber (NS , latitude )
510- print ("Latitude:" , sLatitude , " = " , nLatitude )
511510 sLongitude , nLongitude = latLongAsStringNumber (EW , longitude )
512- print ("Longitude:" , sLongitude , " = " , nLongitude )
513511 zoomLevel = 16
514- print ("OSMaps Link:" , "https://osmaps.ordnancesurvey.co.uk/{0:f}%2C{1:f}%2C{2:d}" .format (nLatitude , nLongitude , zoomLevel )) # No Pn
515- # Google Maps URL API doesn't seem to allow a Pin to be displayed at the lat/long coordinates at the same time as specifying a zoom and a map type
516- print ("Google Link:" , "https://www.google.com/maps/%40?api=1&map_action=map¢er={0:f}%2C{1:f}&zoom={2:d}&basemap=satellite" .format (nLatitude , nLongitude , zoomLevel )) # No pin
517- print ("Google Link with Pin:" , "https://www.google.com/maps/search/?api=1&query={0:f}%2C{1:f}&zoom=10" .format (nLatitude , nLongitude )) # Pin
512+ propertiesDict ['latitude' ] = nLatitude
513+ propertiesDict ['longitude' ] = nLongitude
514+ propertiesDict ['fromGPS' ] = fromGPS
515+ if verbose :
516+ print ("Latitude:" , sLatitude , " = " , nLatitude )
517+ print ("Longitude:" , sLongitude , " = " , nLongitude )
518+ print ("OSMaps Link:" , "https://osmaps.ordnancesurvey.co.uk/{0:f}%2C{1:f}%2C{2:d}" .format (nLatitude , nLongitude , zoomLevel )) # No Pn
519+ # Google Maps URL API doesn't seem to allow a Pin to be displayed at the lat/long coordinates at the same time as specifying a zoom and a map type
520+ print ("Google Link:" , "https://www.google.com/maps/%40?api=1&map_action=map¢er={0:f}%2C{1:f}&zoom={2:d}&basemap=satellite" .format (nLatitude , nLongitude , zoomLevel )) # No pin
521+ print ("Google Link with Pin:" , "https://www.google.com/maps/search/?api=1&query={0:f}%2C{1:f}&zoom=10" .format (nLatitude , nLongitude )) # Pin
518522
519523 if fromGPS and 6 in GPSTags :
520524 altitudeTuple = GPSTags [6 ]['value' ]
521- altitude = altitudeTuple [0 ]/ altitudeTuple [1 ]
522- print ("Rough Altitude:" , "{0:.0f} m" .format (round (altitude , - 2 )))
525+ altitude = round (altitudeTuple [0 ]/ altitudeTuple [1 ], - 2 )
526+ if verbose :
527+ print ("Rough Altitude:" , "{0:.0f} m" .format (altitude ))
528+ propertiesDict ['altitude' ] = altitude
523529
524530 # for k,d in GPSTags.items() :
525531 # print(k, d)
@@ -532,12 +538,23 @@ def summariseTags(allTags) :
532538 if 306 in IFD0Tags :
533539 timestamp = IFD0Tags [306 ]['value' ]
534540 if timestamp [0 :4 ] != "0000" :
535- print ("Timestamp:" , IFD0Tags [306 ]['value' ], "GMT" )
541+ if verbose :
542+ print ("Timestamp:" , IFD0Tags [306 ]['value' ], "GMT" )
543+ propertiesDict ['timestamp' ] = timestamp
536544
537545 if 256 in IFD0Tags and 257 in IFD0Tags :
538- print ("Size:" , IFD0Tags [256 ]['value' ], " x " , IFD0Tags [257 ]['value' ], "pixels" )
546+ columns = IFD0Tags [256 ]['value' ]
547+ rows = IFD0Tags [257 ]['value' ]
548+ if verbose :
549+ print ("Size:" , columns , " x " , rows , "pixels" )
550+ propertiesDict ['columns' ] = columns
551+ propertiesDict ['rows' ] = rows
552+
539553 if 271 in IFD0Tags :
540- print ("Make:" , IFD0Tags [271 ]['value' ])
554+ make = IFD0Tags [271 ]['value' ]
555+ if verbose :
556+ print ("Make:" , make )
557+ propertiesDict ['make' ] = make
541558
542559 # IFD1 = thumbnail
543560 # 256, 257, 259, 274, 282, 283, 296, 512, 514
@@ -558,9 +575,10 @@ def summariseTags(allTags) :
558575###########################################################################
559576##
560577
561- def processFile (filename ) :
578+ def processFile (filename , verbose = True ) :
562579
563- print ("Reading from:" , filename )
580+ if verbose :
581+ print ("Reading from:" , filename )
564582
565583 bytecount = 0
566584 aborted = False
@@ -672,19 +690,20 @@ def processFile(filename) :
672690 bytecount += len (trailingBytes )
673691
674692 # Summarise what we've found
675- for s in segmentsInfo :
676- print (s )
693+ if verbose :
694+ for s in segmentsInfo :
695+ print (s )
677696
678- if EOIFound and trailingBytes :
679- print ("Found" , len (trailingBytes ), "unknown bytes after EOI marker:" , * trailingBytes [0 :10 ], "..." )
697+ if EOIFound and trailingBytes :
698+ print ("Found" , len (trailingBytes ), "unknown bytes after EOI marker:" , * trailingBytes [0 :10 ], "..." )
680699
681700 if not (SOIFound and EOIFound ) :
682- print ("*** Start/End of Image character(s) not found" )
701+ print ("*** Start/End of Image character(s) not found in file:" , filename )
683702
684- if not aborted :
703+ if aborted :
704+ print ("*** Aborted read of file:" , filename )
705+ elif verbose :
685706 print ("Read all bytes:" , bytecount , "bytes" )
686- else :
687- print ("*** Aborted read" )
688707
689708 allTags = {}
690709
@@ -694,32 +713,44 @@ def processFile(filename) :
694713 appName = info ['app' ]
695714 if appName == "Exif" :
696715 Exifdict = processExifSegment (info , data )
697- print ("Extracted these IFDs from the Exif segment:" )
716+ if verbose :
717+ print ("Extracted these IFDs from the Exif segment:" )
698718 for n , d in Exifdict .items () :
699- print ("- " , n , ":" , len (d ), "item(s)" )
719+ if verbose :
720+ print ("- " , n , ":" , len (d ), "item(s)" )
700721 allTags [n ] = d
701722 elif appName == "JFIF" :
702723 JFIFdict = processJFIFSegment (info , data )
703- print ("Extracted JFIF segment data:" , len (JFIFdict ), "item(s)" )
724+ if verbose :
725+ print ("Extracted JFIF segment data:" , len (JFIFdict ), "item(s)" )
704726 allTags ['JFIF' ] = JFIFdict
705727 elif appName == "ICC_PROFILE" :
706728 ICCdict = processICCProfileSegment (info , data )
707- print ("Extracted ICC Profile segment data:" , len (ICCdict ), "item(s)" )
729+ if verbose :
730+ print ("Extracted ICC Profile segment data:" , len (ICCdict ), "item(s)" )
708731 allTags ['ICC' ] = ICCdict
709732 else :
710- print ("Not examining" , appName , " data segment" )
733+ if verbose :
734+ print ("Not examining" , appName , " data segment" )
711735
736+ propertiesDict = {}
737+ propertiesDict ['filename' ] = filename
738+ propertiesDict ['bytes' ] = bytecount
739+ #propertiesDict['segments'] = segmentsInfo
740+ summariseTags (propertiesDict , allTags , verbose )
712741
713- summariseTags (allTags )
714-
742+ return propertiesDict
715743#
716744####################################
717745#
718746
719- if len (sys .argv ) == 1 :
720- print ("No filename command line argument provided" )
721- exit ()
747+ if __name__ == "__main__" :
748+
749+ if len (sys .argv ) == 1 :
750+ print ("No filename command line argument provided" )
751+ exit ()
722752
723- filename = sys .argv [1 ]
724- processFile (filename )
753+ filename = sys .argv [1 ]
754+ mainProperties = processFile (filename , True )
725755
756+ # print(mainProperties)
0 commit comments