def _pyexiv2_new(self, fn): from pyexiv2 import ImageMetadata exif = ImageMetadata(fn) exif.read() self._exif = exif self._getitem = self._new_getitem self._contains = exif.__contains__
def get_exif_metadata3(image_path): metadata = ImageMetadata(image_path) metadata.read() for item in metadata.exif_keys: tag = metadata[item] print(tag) f = open("Exifinfo.txt", "w") f.write(str(tag) + "\n")
def get_exif_metadata3(image_path): metadata = ImageMetadata(image_path) metadata.read() for item in metadata.exif_keys: tag = metadata[item] print(tag) f = open("Exifinfo.txt","w") f.write(str(tag) + "\n")
def getComment(self, filePath): """Function to retrieve comment from JPEG file""" """ Get comment info from the image specified filePath: full path of the image file """ metadata = ImageMetadata(filePath) metadata.read() return metadata.comment
def Extract(foto): metadata = ImageMetadata(foto) metadata.read() for item in metadata.exif_keys: tag = metadata[item] print tag f = open("Exifinfo.txt","a") f.write(str(tag) + "\n")
def exif3meta(image_path): print(GR+' [*] Reading METADATA info...') metadata = ImageMetadata(image_path) metadata.read() print(O+' [!] Found '+GR+str(len(metadata.exif_keys))+O+' keys...') for item in metadata.exif_keys: tag = metadata[item] print(C+' [+] '+str(tag).split('[')[0]+B+' ['+str(tag).split('[')[1].split(']')[0]+'] = '+GR+str(tag).split('=')[1].strip()) time.sleep(0.2)
def write_metadata(src_image, dest_image): meta_source = ImageMetadata(src_image) meta_dest = ImageMetadata(dest_image) meta_dest.read() meta_source.read() for k in meta_source.exif_keys[:]: try: meta_dest[k] = ExifTag(k, meta_source[k].value) except Exception as e: continue meta_dest.write(preserve_timestamps=True)
def fetch_exif(filename): """Load EXIF data from disk. >>> fetch_exif('demo/2010 10 16.gpx') Traceback (most recent call last): IOError: demo/2010 10 16.gpx: The file contains data of an unknown image type >>> type(fetch_exif('demo/IMG_2411.JPG')) <class 'pyexiv2.metadata.ImageMetadata'> """ exif = ImageMetadata(filename) exif.read() return exif
def getExif(self, filename): """Return a dictionary of the metadata. """ ret = {} image = ImageMetadata(filename) try: image.read() except IOError: return ret for tag in image.values(): ret[tag.key] = tag.value return ret
def add_tag_to_picture(filename: str, tag: str): metadata = ImageMetadata(filename) metadata.read() current_tags = [] if 'Exif.Photo.UserComment' in metadata: userdata = json.loads(metadata['Exif.Photo.UserComment'].value) if userdata["tags"] is not None: current_tags = list(userdata["tags"]) tags = [tag] + current_tags metadata = ImageMetadata(filename) metadata.read() userdata = {'tags': tags} metadata['Exif.Photo.UserComment'] = json.dumps(userdata) metadata.write() return True
def read(self): """Load exif data from disk.""" self.exif = ImageMetadata(self.filename) self.timestamp = None self.altitude = None self.latitude = None self.longitude = None self.timezone = None self.manual = False try: self.exif.read() except TypeError: raise IOError Camera(self.exif) # Try to get a thumbnail. try: self.thumb = GdkPixbuf.Pixbuf.new_from_file_at_size( self.filename, self.thm_size, self.thm_size) except GObject.GError: if len(self.exif.previews) > 0: data = self.exif.previews[-1].data elif len(self.exif.exif_thumbnail.data) > 0: data = self.exif.exif_thumbnail.data else: raise IOError self.thumb = GdkPixbuf.Pixbuf.new_from_stream_at_scale( Gio.MemoryInputStream.new_from_data(data, None), self.thm_size, self.thm_size, True, None) self.calculate_timestamp() try: self.latitude = dms_to_decimal( *self.exif[GPS + 'Latitude'].value + [self.exif[GPS + 'LatitudeRef'].value]) self.longitude = dms_to_decimal( *self.exif[GPS + 'Longitude'].value + [self.exif[GPS + 'LongitudeRef'].value]) except KeyError: pass try: self.altitude = float(self.exif[GPS + 'Altitude'].value) if int(self.exif[GPS + 'AltitudeRef'].value) > 0: self.altitude *= -1 except KeyError: pass
def load(self, buffer, extension): self.extension = extension if extension is None: mime = self.get_mimetype(buffer) self.extension = EXTENSION.get(mime, '.jpg') if self.extension == '.svg': buffer = self.convert_svg_to_png(buffer) image_or_frames = self.create_image(buffer) if METADATA_AVAILABLE: try: self.metadata = ImageMetadata.from_buffer(buffer) self.metadata.read() except Exception as e: logger.error('Error reading image metadata: %s' % e) if self.context.config.ALLOW_ANIMATED_GIFS and isinstance( image_or_frames, (list, tuple)): self.image = image_or_frames[0] if len(image_or_frames) > 1: self.multiple_engine = MultipleEngine(self) for frame in image_or_frames: self.multiple_engine.add_frame(frame) self.wrap(self.multiple_engine) else: self.image = image_or_frames if self.source_width is None: self.source_width = self.size[0] if self.source_height is None: self.source_height = self.size[1]
def read(self): """Load exif data from disk.""" self.exif = ImageMetadata(self.filename) self.timestamp = None self.altitude = None self.latitude = None self.longitude = None self.timezone = None self.manual = False try: self.exif.read() except TypeError: raise IOError self.camera = get_camera(self) # Try to get a thumbnail. try: self.thumb = GdkPixbuf.Pixbuf.new_from_file_at_size( self.filename, self.thm_size, self.thm_size) except GObject.GError: if len(self.exif.previews) > 0: data = self.exif.previews[-1].data elif len(self.exif.exif_thumbnail.data) > 0: data = self.exif.exif_thumbnail.data else: raise IOError self.thumb = GdkPixbuf.Pixbuf.new_from_stream_at_scale( Gio.MemoryInputStream.new_from_data(data, None), self.thm_size, self.thm_size, True, None) # If we're reloading, then hide the label and clear the ListStore, # but if we're loading afresh then we'll need a new iter... if self.label is not None: self.label.hide() if self.thm_size < 250: if self.iter is None: self.iter = self.liststore.append() self.liststore.set_row(self.iter, [self.filename, self.long_summary(), self.thumb, self.timestamp]) self.calculate_timestamp() try: self.latitude = dms_to_decimal( *self.exif[GPS + 'Latitude'].value + [self.exif[GPS + 'LatitudeRef'].value] ) self.longitude = dms_to_decimal( *self.exif[GPS + 'Longitude'].value + [self.exif[GPS + 'LongitudeRef'].value] ) except KeyError: pass try: self.altitude = float(self.exif[GPS + 'Altitude'].value) if int(self.exif[GPS + 'AltitudeRef'].value) > 0: self.altitude *= -1 except KeyError: pass
def _read_image_metadata(img): if HAS_PYEXIV2: metadata = ImageMetadata.from_buffer(img) metadata.read() return metadata else: return {}
def remove_tag_from_picture(filename: str, tag: str): metadata = ImageMetadata(filename) metadata.read() if 'Exif.Photo.UserComment' not in metadata: print("Exif.Photo.UserComment does not exist in metadata") return False userdata = json.loads(metadata['Exif.Photo.UserComment'].value) current_tags = [] if userdata["tags"] is not None else list( userdata["tags"]) if len(current_tags) > 0: current_tags.remove(tag) metadata = ImageMetadata(filename) metadata.read() userdata = {'tags': current_tags} metadata['Exif.Photo.UserComment'] = json.dumps(userdata) metadata.write() return True
def parsePhoto(self, photoPwd): chdir(photoPwd) for photo in listdir(photoPwd): if path.isfile(photo): metadata = ImageMetadata(photo) metadata.read() dt = metadata['Exif.Photo.DateTimeOriginal'].value _datetime, coord = self.getCoord(dt) #metadata['GPS.GPSVersionID'] = '2.2.0.0' #metadata['GPS.GPSLatitude'] = 0 #metadata['GPS.GPSLongitude'] = 2 #metadata[''] = 3 #metadata.write() print '%s %s %s %s' % (photo, dt, _datetime, coord)
def trigger_expose_bulb(camera, bulb, start_time=(monotonic_time() + 0.05), meta=[], download_timeout=3.5): end_time = start_time + bulb monotonic_alarm(start_time) gph_cmd(camera.bulb_begin) monotonic_alarm(end_time) gph_cmd(camera.bulb_end) o = gph_cmd('wait-event-and-download %is' % int(floor(download_timeout)), timeout=download_timeout) # Should download the image s = filter(lambda x: x.startswith(_saving_file_response), o) if len(s) != 1: print("Couldn't retrieve file at the end of bulb exposure.") raise IOError filename = s[0][len(_saving_file_response):] exifd = ImageMetadata(filename) exifd.read() # Add a piece of debug info to exif header meta.append(('BulbHoldTime', bulb)) meta.append(('TriggerStartTime', start_time)) for (name, value) in meta: tag = 'Xmp.xmp.GPhotolapser.' + name exifd[tag] = XmpTag(tag, value=str(value)) exifd.write() return filename
def trigger_capture(camera, shutter, start_time=(monotonic_time() + 0.05), meta=[], download_timeout=5.0): monotonic_alarm(start_time) o = gph_cmd('capture-image-and-download', timeout=shutter + download_timeout) s = filter(lambda x: x.startswith(_saving_file_response), o) if len(s) != 1: print("Couldn't retrieve file at the end of capture.") raise IOError filename = s[0][len(_saving_file_response):] exifd = ImageMetadata(filename) exifd.read() # Add a piece of debug info to exif header meta.append(('TriggerStartTime', start_time)) for (name, value) in meta: tag = 'Xmp.xmp.GPhotolapser.' + name exifd[tag] = XmpTag(tag, value=str(value)) exifd.write() return filename
def correctRotaion(fl_input): print("imageProcessing::correctRotaion(fl_input)") try: # save the result metadata = ImageMetadata(fl_input) metadata.read() # Get the thumbnail of the image from EXIF. thumb = metadata.exif_thumbnail thumb.set_from_file(fl_input) thumb.write_to_file('512_' + "a") thumb.erase() # Rewrite the thumbnail with corrected image. metadata.write() # Return the output file name. return (True) except Exception as e: print("Error occurs in imageProcessing::correctRotaion(in_file)") print(str(e)) error.ErrorMessageImageProcessing(details=str(e), show=True, language="en") return (None)
def all_photos_in_dir(photo_dir: str, year: str, date: str) -> dict: today_photos = {} if os.path.isdir(photo_dir): for file in os.listdir(photo_dir): if file.lower().endswith( ('.png', '.jpg', '.jpeg', '.tiff', '.bmp', '.gif')): tags = [] try: file_name = "./static/photos/" + year + "/" + date + "/" + file metadata = ImageMetadata(file_name) metadata.read() if 'Exif.Photo.UserComment' in metadata: userdata = json.loads( metadata['Exif.Photo.UserComment'].value) if userdata["tags"] is not None: tags = list(userdata["tags"]) except Exception as e: logger.error(e) today_photos[year + "/" + date + "/" + file] = tags if file.lower().endswith('.mp4'): today_photos[year + "/" + date + "/" + file] = [] return today_photos
def index(source, destination_dir): """ @param source Source filename to copy. @param destinationDir Destination base directory to copy source to. Final directory name is determined from file. """ try: # Load EXIF information metadata = ImageMetadata(source) metadata.read() # Read the date/time at which the picture was taken tag = metadata['Exif.Image.DateTime'] mtime = tag.value.timetuple() log.debug('Successfully read EXIF from "{s}"'.format(s=source)) except Exception as e: log.debug(e) # Get the last modification time mtime = gmtime(getmtime(source)) # Destination filename destination = join(destination_dir, strftime('%Y', mtime), strftime('%Y-%m-%d', mtime)) # Directory must exist if not isdir(destination): log.debug(f'Create directory: "{destination}"') makedirs(destination, 0o755) # Append filename from source destination = join(destination, basename(source)) log.debug(f'Destination: "{destination}"') # Check if file already exists, skip if it does if exists(destination): log.info('Skipping "{d}", file already exists'.format(d=destination)) return log.info('Copying file "{s}" to directory "{d}"'.format(s=source, d=destination)) # Copy file copy(source, destination)
def read(self): """Load exif data from disk.""" self.exif = ImageMetadata(self.filename) self.timestamp = None self.altitude = None self.latitude = None self.longitude = None self.timezone = None self.manual = False try: self.exif.read() except TypeError: raise IOError Camera(self.exif) # Try to get a thumbnail. try: self.thumb = GdkPixbuf.Pixbuf.new_from_file_at_size( self.filename, self.thm_size, self.thm_size) except GObject.GError: if len(self.exif.previews) > 0: data = self.exif.previews[-1].data elif len(self.exif.exif_thumbnail.data) > 0: data = self.exif.exif_thumbnail.data else: raise IOError self.thumb = GdkPixbuf.Pixbuf.new_from_stream_at_scale( Gio.MemoryInputStream.new_from_data(data, None), self.thm_size, self.thm_size, True, None) self.calculate_timestamp() try: self.latitude = dms_to_decimal( *self.exif[GPS + 'Latitude'].value + [self.exif[GPS + 'LatitudeRef'].value] ) self.longitude = dms_to_decimal( *self.exif[GPS + 'Longitude'].value + [self.exif[GPS + 'LongitudeRef'].value] ) except KeyError: pass try: self.altitude = float(self.exif[GPS + 'Altitude'].value) if int(self.exif[GPS + 'AltitudeRef'].value) > 0: self.altitude *= -1 except KeyError: pass
def read_meta(src, dest): try: s = ImageMetadata(src) s.read() d = ImageMetadata(dest) d.read() except: print 'Unable to read the metadata for source or dest image.' raise return s, d
def setComment(self, filePath, comment): """ Set comment info to the image specified filePath: full path of the image file comment: contains comment tag info """ metadata = ImageMetadata(filePath) metadata.read() try: metadata.comment = comment metadata.write() return True except Exception as e: return False
def write(self, fname, instr, date, time, xaxis, yaxis, xunits, yunits, filter): metadata = ImageMetadata(fname) metadata.read() userdata = { 'File name': fname, 'Instrument': instr, 'Date': date, 'Time': time, 'X-Axis': xaxis, 'X-units': xunits, 'Y-units': yunits, 'Y-Axis': yaxis, 'Filter': filter, } metadata['Exif.Photo.UserComment'] = json.dumps(userdata) metadata.write()
def __init__(self, dirname, filename): self.path = dirname + '/' + filename #improve this using os.utils and concatenate locations self.filename = filename self.dirname = dirname self.id = str(uuid.uuid4()) self.thumb = self.generate_thumbnail() try: self.metadata = Metadata(self.path) self.metadata.read() except IOError: print "File " + self.path + " is not a valid image file" try: self.lng_tuple = self.metadata['Exif.GPSInfo.GPSLongitude'] self.lat_tuple = self.metadata['Exif.GPSInfo.GPSLatitude'] self.lng = self.coord_to_decimal(self.lng_tuple) self.lat = self.coord_to_decimal(self.lat_tuple) self.lng_ref = self.metadata['Exif.GPSInfo.GPSLongitudeRef'].value self.lat_ref = self.metadata['Exif.GPSInfo.GPSLatitudeRef'].value if(self.lng_ref == 'W'): self.lng = - self.lng if(self.lat_ref == 'S'): self.lat = - self.lat except KeyError: self.lng = 0 self.lat = 0 print "GPS tags not available for " + self.filename
Minimalistic example of how to load and display with pygtk the thumbnail data extracted from an image. The path to the image file from which the thumbnail data should be extracted should be passed as the only argument of the script. It is of course assumed that you have pygtk installed. """ if (len(sys.argv) != 2): print 'Usage: ' + sys.argv[0] + ' path/to/picture/file/containing/jpeg/thumbnail' sys.exit(1) app = gtk.Window(gtk.WINDOW_TOPLEVEL) app.connect('destroy', lambda app: gtk.main_quit()) # Load the image, read the metadata and extract the thumbnail data metadata = ImageMetadata(sys.argv[1]) metadata.read() previews = metadata.previews if not previews: print "This image doesn't contain any thumbnail." sys.exit(1) # Get the largest preview available preview = previews[-1] # Create a pixbuf loader to read the thumbnail data pbloader = gtk.gdk.PixbufLoader() pbloader.write(preview.data) # Get the resulting pixbuf and build an image to be displayed pixbuf = pbloader.get_pixbuf() pbloader.close()
def get_datetime_of_image(img_path: Path) -> datetime: meta = ImageMetadata(str(img_path)) meta.read() return meta.get("Exif.Image.DateTime").value
def save(self, *args, **kwargs): if self.pk == None: # Only do this when adding a new item metadata = ImageMetadata.from_buffer(self.image.read(1024*1024)) # 1MB should be enough to get Exif tags metadata.read() self.date_taken = metadata['Exif.Photo.DateTimeOriginal'].value super(Photo, self).save(*args, **kwargs) # Call the "real" save() method.
print 'Error determining version numbers.' sys.exit(0) if (ver_libexiv2 < ver_libexiv2_min): print 'Newer version of libexiv2 required.' sys.exit(1) if (ver_pyexiv2 < ver_pyexiv2_min): print 'Newer version of pyexiv2 required.' sys.exit(1) if (len(sys.argv) != 3): print 'Usage: ' + sys.argv[0] + ' <sourcefile> <targetfile>' sys.exit(1) # Load the image, read the metadata and extract the thumbnail data src_metadata = ImageMetadata(sys.argv[1]) src_metadata.read() tgt_metadata = ImageMetadata(sys.argv[2]) tgt_metadata.read() for groupName, tagList in copy_tags.iteritems(): # print groupName # print tagList for i, tagName in enumerate(tagList): fullkey = 'Exif.' + groupName + '.' + tagName try: tag = src_metadata[fullkey] print fullkey + ': ' + tag.raw_value except KeyError: print "WARNING: can't find EXIF key '" + fullkey + "'"
class GPSImage: def __init__(self, dirname, filename): self.path = dirname + '/' + filename #improve this using os.utils and concatenate locations self.filename = filename self.dirname = dirname self.id = str(uuid.uuid4()) self.thumb = self.generate_thumbnail() try: self.metadata = Metadata(self.path) self.metadata.read() except IOError: print "File " + self.path + " is not a valid image file" try: self.lng_tuple = self.metadata['Exif.GPSInfo.GPSLongitude'] self.lat_tuple = self.metadata['Exif.GPSInfo.GPSLatitude'] self.lng = self.coord_to_decimal(self.lng_tuple) self.lat = self.coord_to_decimal(self.lat_tuple) self.lng_ref = self.metadata['Exif.GPSInfo.GPSLongitudeRef'].value self.lat_ref = self.metadata['Exif.GPSInfo.GPSLatitudeRef'].value if(self.lng_ref == 'W'): self.lng = - self.lng if(self.lat_ref == 'S'): self.lat = - self.lat except KeyError: self.lng = 0 self.lat = 0 print "GPS tags not available for " + self.filename #The EXIF data may optionally embed a thumbnail in the JPEG or TIFF format. The thumbnail can be accessed, set from a JPEG file or buffer, saved to disk and erased: #thumb = metadata.exif_thumbnail #thumb.set_from_file('/tmp/thumbnail.jpg') #thumb.write_to_file('/tmp/copy') #thumb.erase() #metadata.write() def generate_thumbnail(self): ext = ".jpg" thumbs_dir = self.create_thumbs_dir() thumb_img = thumbs_dir + self.filename.split(".")[0] + "_thumb" + ext if os.path.exists(thumb_img): print "Thumb for " + self.filename + " found & skipped." return thumb_img image = Image.open(self.path) image = image.resize((128, 128), Image.ANTIALIAS) image.save(thumb_img) return thumb_img def create_thumbs_dir(self): dir_path = self.dirname + "/.thumbs/" if not os.path.exists(dir_path): os.makedirs(dir_path) return dir_path def print_gps_data(self): keys = [ 'Exif.GPSInfo.GPSMeasureMode', 'Exif.GPSInfo.GPSVersionID', 'Exif.GPSInfo.GPSLatitudeRef', 'Exif.GPSInfo.GPSLatitude', 'Exif.GPSInfo.GPSLongitudeRef', 'Exif.GPSInfo.GPSLongitude', 'Exif.GPSInfo.GPSTimeStamp', 'Exif.GPSInfo.GPSSatellites' ] for key in keys: print self.metadata[key].raw_value def print_coords(self): print 'Longitude: ' + str(self.lng) print 'Latitude: ' + str(self.lat) print '' def coord_to_decimal(self, coord): (degree, minute, second) = coord.value return (float(degree.numerator)/degree.denominator + float(minute.numerator)/minute.denominator/60 + float(second.numerator)/second.denominator/3600)
def __init__(self, path): self.path = path md = ImageMetadata(self.path) md.read() self.date = md['Exif.Image.DateTime'].value self.shutter = md['Exif.Nikon3.ShutterCount'].value
class Photograph(Coordinates): """Represents a single photograph and it's location in space and time.""" liststore = get_obj('loaded_photos') def __init__(self, filename, thumb_size=200): """Initialize new Photograph object's attributes with default values.""" self.filename = filename self.thm_size = thumb_size self.label = None self.exif = None self.thumb = None self.manual = None self.camera = None self.iter = None def read(self): """Load exif data from disk.""" self.exif = ImageMetadata(self.filename) self.timestamp = None self.altitude = None self.latitude = None self.longitude = None self.timezone = None self.manual = False try: self.exif.read() except TypeError: raise IOError self.camera = get_camera(self) # Try to get a thumbnail. try: self.thumb = GdkPixbuf.Pixbuf.new_from_file_at_size( self.filename, self.thm_size, self.thm_size) except GObject.GError: if len(self.exif.previews) > 0: data = self.exif.previews[-1].data elif len(self.exif.exif_thumbnail.data) > 0: data = self.exif.exif_thumbnail.data else: raise IOError self.thumb = GdkPixbuf.Pixbuf.new_from_stream_at_scale( Gio.MemoryInputStream.new_from_data(data, None), self.thm_size, self.thm_size, True, None) # If we're reloading, then hide the label and clear the ListStore, # but if we're loading afresh then we'll need a new iter... if self.label is not None: self.label.hide() if self.thm_size < 250: if self.iter is None: self.iter = self.liststore.append() self.liststore.set_row(self.iter, [self.filename, self.long_summary(), self.thumb, self.timestamp]) self.calculate_timestamp() try: self.latitude = dms_to_decimal( *self.exif[GPS + 'Latitude'].value + [self.exif[GPS + 'LatitudeRef'].value] ) self.longitude = dms_to_decimal( *self.exif[GPS + 'Longitude'].value + [self.exif[GPS + 'LongitudeRef'].value] ) except KeyError: pass try: self.altitude = float(self.exif[GPS + 'Altitude'].value) if int(self.exif[GPS + 'AltitudeRef'].value) > 0: self.altitude *= -1 except KeyError: pass def calculate_timestamp(self): """Determine the timestamp based on the currently selected timezone. This method relies on the TZ environment variable to be set before it is called. If you don't set TZ before calling this method, then it implicitely assumes that the camera and the computer are set to the same timezone. """ try: self.timestamp = int(mktime( self.exif['Exif.Photo.DateTimeOriginal'].value.timetuple())) except KeyError: self.timestamp = int(stat(self.filename).st_mtime) self.timestamp += self.camera.get_offset() if self.label is not None: auto_timestamp_comparison(self) def write(self): """Save exif data to photo file on disk.""" if self.altitude is not None: self.exif[GPS + 'Altitude'] = float_to_rational(self.altitude) self.exif[GPS + 'AltitudeRef'] = '0' if self.altitude >= 0 else '1' self.exif[GPS + 'Latitude'] = decimal_to_dms(self.latitude) self.exif[GPS + 'LatitudeRef'] = 'N' if self.latitude >= 0 else 'S' self.exif[GPS + 'Longitude'] = decimal_to_dms(self.longitude) self.exif[GPS + 'LongitudeRef'] = 'E' if self.longitude >= 0 else 'W' self.exif[GPS + 'MapDatum'] = 'WGS-84' self.exif.write() modified.discard(self) self.liststore.set_value(self.iter, 1, self.long_summary()) def set_location(self, lat, lon, ele=None): """Alter the coordinates of this photo.""" if ele is not None: self.altitude = ele self.latitude = lat self.longitude = lon self.position_label() self.lookup_geoname() self.modify_summary() def modify_summary(self): """Update the text displayed in the GtkListStore.""" modified.add(self) self.liststore.set_value(self.iter, 1, ('<b>%s</b>' % self.long_summary())) def position_label(self): """Maintain correct position and visibility of ChamplainLabel.""" if self.label.get_parent() is None: return if self.valid_coords(): self.label.set_location(self.latitude, self.longitude) self.label.show() if self.label.get_selected(): self.label.raise_top() else: self.label.hide() def set_label_highlight(self, highlight, transparent): """Set the highlightedness of the given photo's ChamplainLabel.""" if self.label.get_property('visible'): self.label.set_scale(*[1.1 if highlight else 1] * 2) self.label.set_selected(highlight) self.label.set_opacity(64 if transparent and not highlight else 255) if highlight: self.label.raise_top() def set_geodata(self, data): """Override Coordinates.set_geodata to apply directly into IPTC.""" city, state, country, tz = data self.exif[IPTC + 'City'] = [city or ''] self.exif[IPTC + 'ProvinceState'] = [get_state(country, state) or ''] self.exif[IPTC + 'CountryName'] = [get_country(country) or ''] self.exif[IPTC + 'CountryCode'] = [country or ''] self.timezone = tz.strip() self.camera.set_found_timezone(self.timezone) def pretty_geoname(self): """Override Coordinates.pretty_geoname to read from IPTC.""" names = [] for key in [ 'City', 'ProvinceState', 'CountryName' ]: try: names.extend(self.exif[IPTC + key].values) except KeyError: pass return ', '.join([name for name in names if name]) def destroy(self): """Agony!""" self.label.unmap() self.label.destroy() self.camera.photos.discard(self) del photos[self.filename] modified.discard(self) self.liststore.remove(self.iter)
data extracted from an image. The path to the image file from which the thumbnail data should be extracted should be passed as the only argument of the script. It is of course assumed that you have pygtk installed. """ if (len(sys.argv) != 2): print 'Usage: ' + sys.argv[ 0] + ' path/to/picture/file/containing/jpeg/thumbnail' sys.exit(1) app = gtk.Window(gtk.WINDOW_TOPLEVEL) app.connect('destroy', lambda app: gtk.main_quit()) # Load the image, read the metadata and extract the thumbnail data metadata = ImageMetadata(sys.argv[1]) metadata.read() previews = metadata.previews if not previews: print "This image doesn't contain any thumbnail." sys.exit(1) # Get the largest preview available preview = previews[-1] # Create a pixbuf loader to read the thumbnail data pbloader = gtk.gdk.PixbufLoader() pbloader.write(preview.data) # Get the resulting pixbuf and build an image to be displayed pixbuf = pbloader.get_pixbuf() pbloader.close()
# -*- coding: utf-8 -*- from pyexiv2 import ImageMetadata import sys, os from datetime import datetime, date def print_key_value(metadata, key): print key, '=', metadata[key] if __name__ == '__main__': # Read an image file's metadata image_file = sys.argv[1] metadata = ImageMetadata(image_file) metadata.read() # Print a list of all the keys of the EXIF tags in the image print 'EXIF keys:', metadata.exif_keys try: # Print the value of the Exif.Image.DateTime tag key = 'Exif.Image.DateTime' print_key_value(metadata, key) # Set the value of the Exif.Image.DateTime tag metadata[key] = datetime.now() print_key_value(metadata, key) except KeyError: print '[not set]'
def test3(self, fname): metadata = ImageMetadata(fname) metadata.read() userdata = json.loads(metadata['Exif.Photo.UserComment'].value) pprint.pprint(userdata)
from pyexiv2 import ImageMetadata if __name__ == '__main__': metadata1 = ImageMetadata('IMG_TEST_001.jpg') metadata1.read() info1 = metadata1._get_comment() print 'EXIF keys:', metadata1.exif_keys #img.close()
# -*- coding: utf-8 -*- from pyexiv2 import ImageMetadata, ExifTag metadata = ImageMetadata('img.jpg') metadata.read() for item in metadata.exif_keys: tag = metadata[item] print tag f = open("Exifinfo.txt","a") f.write(str(tag) + "\n")
def read_exif(self, input_temp_file): fields = [ 'ImageSize', 'ProfileDescription', 'ColorType', 'FileType', 'Transparency' ] fields += self.context.config.EXIF_FIELDS_TO_KEEP command = [ '-s', '-s', ] command += ['-{0}'.format(i) for i in fields] # T172556 We read EXIF Orientation with pyexiv2 because exiftool is # unreliable for that field (overzealous in the way it interprets the field). # We can't replace all use of exiftool with pyexiv2 because ICC profile # support was only introduced in exiv2 0.26 (not available on Jessie yet) # and it can only extract the ICC profile, not get its name/description upfront. # Which would make the sRGB replacement more difficult (it's unclear how many # variations of the binary content for that family of profiles there are). metadata = ImageMetadata(input_temp_file.name) try: # T178072 pyexviv2 writes to stderr even if the exception is caught logging.disable(logging.ERROR) metadata.read() logging.disable(logging.NOTSET) if 'Exif.Image.Orientation' in metadata.exif_keys: # Distinctive key name to avoid colliding with EXIF_FIELDS_TO_KEEP self.exif['Pyexiv2Orientation'] = metadata.get('Exif.Image.Orientation').value except IOError: logging.disable(logging.NOTSET) self.debug('[IM] Could not read EXIF with pyexiv2') stdout = Engine.exiftool.command( context=self.context, pre=command, input_temp_file=input_temp_file ) for s in stdout.splitlines(): values = s.split(': ', 1) self.exif[values[0]] = values[1] self.debug('[IM] EXIF: %r' % self.exif) if 'ImageSize' in self.exif: self.internal_size = map(int, self.exif['ImageSize'].split('x')) else: # Have not been able to find a test file where that EXIF field comes up unpopulated self.internal_size = (1, 1) # pragma: no cover # If we encounter any non-sRGB ICC profile, we save it to re-apply # it to the result if 'ProfileDescription' not in self.exif: self.debug('[IM] File has no ICC profile') return expected_profile = self.context.config.EXIF_TINYRGB_ICC_REPLACE.lower() profile = self.exif['ProfileDescription'].lower() if profile == expected_profile: self.icc_profile_path = self.context.config.EXIF_TINYRGB_PATH self.debug('[IM] File has sRGB profile') return self.debug('[IM] File has non-sRGB profile') command = [ '-icc_profile', '-b', '-m', ] self.icc_profile_saved = Engine.exiftool.command( context=self.context, pre=command, input_temp_file=input_temp_file )
class Photograph(Coordinates): """Represents a single photograph and it's location in space and time.""" def __init__(self, filename, callback, thumb_size=200): """Initialize new Photograph object's attributes with default values.""" self.filename = filename self.callback = callback self.thm_size = thumb_size self.label = None self.iter = None self.exif = None self.thumb = None self.manual = None def read(self): """Load exif data from disk.""" self.exif = ImageMetadata(self.filename) self.timestamp = None self.altitude = None self.latitude = None self.longitude = None self.timezone = None self.manual = False try: self.exif.read() except TypeError: raise IOError Camera(self.exif) # Try to get a thumbnail. try: self.thumb = GdkPixbuf.Pixbuf.new_from_file_at_size( self.filename, self.thm_size, self.thm_size) except GObject.GError: if len(self.exif.previews) > 0: data = self.exif.previews[-1].data elif len(self.exif.exif_thumbnail.data) > 0: data = self.exif.exif_thumbnail.data else: raise IOError self.thumb = GdkPixbuf.Pixbuf.new_from_stream_at_scale( Gio.MemoryInputStream.new_from_data(data, None), self.thm_size, self.thm_size, True, None) self.calculate_timestamp() try: self.latitude = dms_to_decimal( *self.exif[GPS + 'Latitude'].value + [self.exif[GPS + 'LatitudeRef'].value] ) self.longitude = dms_to_decimal( *self.exif[GPS + 'Longitude'].value + [self.exif[GPS + 'LongitudeRef'].value] ) except KeyError: pass try: self.altitude = float(self.exif[GPS + 'Altitude'].value) if int(self.exif[GPS + 'AltitudeRef'].value) > 0: self.altitude *= -1 except KeyError: pass def calculate_timestamp(self): """Determine the timestamp based on the currently selected timezone. This method relies on the TZ environment variable to be set before it is called. If you don't set TZ before calling this method, then it implicitely assumes that the camera and the computer are set to the same timezone. """ try: self.timestamp = int(mktime( self.exif['Exif.Photo.DateTimeOriginal'].value.timetuple())) except KeyError: self.timestamp = int(stat(self.filename).st_mtime) def write(self): """Save exif data to photo file on disk.""" if self.altitude is not None: self.exif[GPS + 'Altitude'] = float_to_rational(self.altitude) self.exif[GPS + 'AltitudeRef'] = '0' if self.altitude >= 0 else '1' self.exif[GPS + 'Latitude'] = decimal_to_dms(self.latitude) self.exif[GPS + 'LatitudeRef'] = 'N' if self.latitude >= 0 else 'S' self.exif[GPS + 'Longitude'] = decimal_to_dms(self.longitude) self.exif[GPS + 'LongitudeRef'] = 'E' if self.longitude >= 0 else 'W' self.exif[GPS + 'MapDatum'] = 'WGS-84' self.exif.write() def set_location(self, lat, lon, ele=None): """Alter the coordinates of this photo.""" if ele is not None: self.altitude = ele self.latitude = lat self.longitude = lon self.position_label() self.lookup_geoname() self.callback(self) def position_label(self): """Maintain correct position and visibility of ChamplainLabel.""" if self.valid_coords(): self.label.set_location(self.latitude, self.longitude) self.label.show() if self.label.get_selected(): self.label.raise_top() else: self.label.hide() def set_label_highlight(self, highlight, transparent): """Set the highlightedness of the given photo's ChamplainLabel.""" if self.label.get_property('visible'): self.label.set_scale(*[1.1 if highlight else 1] * 2) self.label.set_selected(highlight) self.label.set_opacity(64 if transparent and not highlight else 255) if highlight: self.label.raise_top() def set_geodata(self, data): """Override Coordinates.set_geodata to apply directly into IPTC.""" city, state, country, tz = data self.exif[IPTC + 'City'] = [city or ''] self.exif[IPTC + 'ProvinceState'] = [get_state(country, state) or ''] self.exif[IPTC + 'CountryName'] = [get_country(country) or ''] self.exif[IPTC + 'CountryCode'] = [country or ''] self.timezone = tz.strip() def pretty_geoname(self): """Override Coordinates.pretty_geoname to read from IPTC.""" names = [] for key in [ 'City', 'ProvinceState', 'CountryName' ]: try: names.extend(self.exif[IPTC + key].values) except KeyError: pass length = sum(map(len, names)) return format_list(names, ',\n' if length > 35 else ', ')
# -*- coding: utf-8 -*- from pyexiv2 import ImageMetadata, ExifTag metadata = ImageMetadata(raw_input("Foto: ")) metadata.read() for item in metadata.exif_keys: tag = metadata[item] print tag f = open("Exifinfo.txt", "a") f.write(str(tag) + "\n")
def load_exif_data(file): """ Load EXIF data from source file """ metadata = ImageMetadata(file) metadata.read() return metadata
class Photograph(Coordinates): """Represents a single photograph and it's location in space and time.""" def __init__(self, filename, callback, thumb_size=200): """Initialize new Photograph object's attributes with default values.""" self.filename = filename self.callback = callback self.thm_size = thumb_size self.label = None self.iter = None self.exif = None self.thumb = None self.manual = None def read(self): """Load exif data from disk.""" self.exif = ImageMetadata(self.filename) self.timestamp = None self.altitude = None self.latitude = None self.longitude = None self.timezone = None self.manual = False try: self.exif.read() except TypeError: raise IOError Camera(self.exif) # Try to get a thumbnail. try: self.thumb = GdkPixbuf.Pixbuf.new_from_file_at_size( self.filename, self.thm_size, self.thm_size) except GObject.GError: if len(self.exif.previews) > 0: data = self.exif.previews[-1].data elif len(self.exif.exif_thumbnail.data) > 0: data = self.exif.exif_thumbnail.data else: raise IOError self.thumb = GdkPixbuf.Pixbuf.new_from_stream_at_scale( Gio.MemoryInputStream.new_from_data(data, None), self.thm_size, self.thm_size, True, None) self.calculate_timestamp() try: self.latitude = dms_to_decimal( *self.exif[GPS + 'Latitude'].value + [self.exif[GPS + 'LatitudeRef'].value]) self.longitude = dms_to_decimal( *self.exif[GPS + 'Longitude'].value + [self.exif[GPS + 'LongitudeRef'].value]) except KeyError: pass try: self.altitude = float(self.exif[GPS + 'Altitude'].value) if int(self.exif[GPS + 'AltitudeRef'].value) > 0: self.altitude *= -1 except KeyError: pass def calculate_timestamp(self): """Determine the timestamp based on the currently selected timezone. This method relies on the TZ environment variable to be set before it is called. If you don't set TZ before calling this method, then it implicitely assumes that the camera and the computer are set to the same timezone. """ try: self.timestamp = int( mktime(self.exif['Exif.Photo.DateTimeOriginal'].value. timetuple())) except KeyError: self.timestamp = int(stat(self.filename).st_mtime) def write(self): """Save exif data to photo file on disk.""" if self.altitude is not None: self.exif[GPS + 'Altitude'] = float_to_rational(self.altitude) self.exif[GPS + 'AltitudeRef'] = '0' if self.altitude >= 0 else '1' self.exif[GPS + 'Latitude'] = decimal_to_dms(self.latitude) self.exif[GPS + 'LatitudeRef'] = 'N' if self.latitude >= 0 else 'S' self.exif[GPS + 'Longitude'] = decimal_to_dms(self.longitude) self.exif[GPS + 'LongitudeRef'] = 'E' if self.longitude >= 0 else 'W' self.exif[GPS + 'MapDatum'] = 'WGS-84' self.exif.write() def set_location(self, lat, lon, ele=None): """Alter the coordinates of this photo.""" if ele is not None: self.altitude = ele self.latitude = lat self.longitude = lon self.position_label() self.lookup_geoname() self.callback(self) def position_label(self): """Maintain correct position and visibility of ChamplainLabel.""" if self.valid_coords(): self.label.set_location(self.latitude, self.longitude) self.label.show() if self.label.get_selected(): self.label.raise_top() else: self.label.hide() def set_label_highlight(self, highlight, transparent): """Set the highlightedness of the given photo's ChamplainLabel.""" if self.label.get_property('visible'): self.label.set_scale(*[1.1 if highlight else 1] * 2) self.label.set_selected(highlight) self.label.set_opacity( 64 if transparent and not highlight else 255) if highlight: self.label.raise_top() def set_geodata(self, data): """Override Coordinates.set_geodata to apply directly into IPTC.""" city, state, country, tz = data self.exif[IPTC + 'City'] = [city or ''] self.exif[IPTC + 'ProvinceState'] = [get_state(country, state) or ''] self.exif[IPTC + 'CountryName'] = [get_country(country) or ''] self.exif[IPTC + 'CountryCode'] = [country or ''] self.timezone = tz.strip() def pretty_geoname(self): """Override Coordinates.pretty_geoname to read from IPTC.""" names = [] for key in ['City', 'ProvinceState', 'CountryName']: try: names.extend(self.exif[IPTC + key].values) except KeyError: pass length = sum(map(len, names)) return format_list(names, ',\n' if length > 35 else ', ')
def post(self, img, album): if not os.path.exists(img): raise FileNotFound('Can\'t find image %s on the disk' % img) logger = logging.getLogger('YaFotki.post') opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cookies), MultipartPostHandler.MultipartPostHandler) filename = os.path.split(img)[-1] tags = '' title = filename description = '' if ImageMetadata: exif = ImageMetadata(img) try: tags = ','.join([tag.decode('utf8') for tag in exif['Iptc.Application2.Keywords']]) except KeyError: pass try: title = exif['Iptc.Application2.ObjectName'].decode('utf8') except KeyError: pass try: description = exif['Exif.Image.ImageDescription'].decode('utf8') or exif['Iptc.Application2.Caption'].decode('utf8') except KeyError: pass source = open(img, 'rb') source.seek(0, 2) file_size = source.tell() piece_size = 64000 sid = str(int(time.time())) source.seek(0) hash = md5(source.read()).hexdigest() logger.debug('md5hash: %s, sid: %s, file-size: %s, piece-size: %s' % (hash, sid, file_size, piece_size)) logger.debug('title: %s, description: %s tags: %s' % (title, description, tags)) logger.debug('photo-start') # START fake_file = StringIO((u'<?xml version="1.0" encoding="utf-8"?><client-upload md5="%(md5)s" cookie="%(md5)s%(sid)s"><filename>%(filename)s</filename><title>%(title)s</title><description>%(description)s</description><albumId>%(album)s</albumId><copyright>0</copyright><tags>%(tags)s</tags></client-upload>' % { 'md5': hash, 'sid': sid, 'filename': filename, 'title': title, 'album': album, 'tags': tags, 'description': description, }).encode('utf8')) params = { 'query-type': 'photo-start', 'file-size': str(file_size), 'piece-size': str(piece_size), 'checksum': hash, 'client-xml': fake_file, } try: data = opener.open(UPLOAD_URL, params).read() logger.debug(data) response = minidom.parseString(data).firstChild a = response.attributes if a['status'].value == 'error': if a['exception'].value == '3': logger.error('Album with id %s does not exist.' % album) else: logger.error('Error during upload, with code %s' % a['exception'].value) sys.exit(1) upload_cookie = str(a['cookie'].value) except urllib2.URLError, err: logger.error(err) logger.error(err.read()) return err
#!/usr/bin/python from pyexiv2 import ImageMetadata import os import time from gi.repository import GdkPixbuf dir = '/d/Pics/Wallpapers/Favorites' s = time.time() i = 0 for i, f in enumerate(os.listdir(dir)): try: file = os.path.join(dir, f) GdkPixbuf.Pixbuf.get_file_info(file) except Exception: pass print i, time.time() - s s = time.time() i = 0 for i, f in enumerate(os.listdir(dir)): try: file = os.path.join(dir, f) meta = ImageMetadata(file) meta.read() except Exception: pass print i, time.time() - s