Пример #1
0
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
Пример #2
0
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)
Пример #3
0
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
Пример #4
0
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)
Пример #5
0
	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
Пример #6
0
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
Пример #7
0
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
Пример #8
0
    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()
Пример #9
0
    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 + "'"

            tgt_metadata[fullkey] = tag

    # we're done, so write the updates to the target file (preserving
    # the file's timestamps via the 'True' parameter)
    tgt_metadata.write(True)
Пример #10
0
    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 + "'"

            tgt_metadata[fullkey] = tag

    # we're done, so write the updates to the target file (preserving
    # the file's timestamps via the 'True' parameter)
    tgt_metadata.write(True)
Пример #11
0
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)
Пример #12
0
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 ', ')
Пример #13
0
        print '[not set]'

    # Add a new tag
    key = 'Iptc.Application2.Keywords'
    keywords = ['little', 'big', 'man']
    metadata[key] = keywords
    print_key_value(metadata, key)

    # Print a list of all the keys of the XMP tags in the image
    print os.linesep, 'XMP keys:', metadata.xmp_keys

    try:
        # Print the value of the Xmp.dc.subject tag
        key = 'Xmp.dc.subject'
        print_key_value(metadata, key)

        # Set the value of the Xmp.dc.subject tag
        metadata[key] = keywords
        print_key_value(metadata, key)
    except KeyError:
        print '[not set]'

    # Add a new tag
    key = 'Xmp.dc.title'
    metadata[key] = {'x-default': 'Sunset', 'fr': 'Coucher de soleil'}
    print_key_value(metadata, key)

    # Write back the metadata to the file
    metadata.write()

Пример #14
0
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 ', ')