Example #1
0
 def test_pickle_exif_tag(self):
     tags = []
     tags.append(ExifTag('Exif.Image.DateTime',
                         datetime.datetime(2010, 12, 22, 19, 21, 0)))
     tags.append(ExifTag('Exif.GPSInfo.GPSDateStamp', datetime.date.today()))
     tags.append(ExifTag('Exif.Image.Copyright', '(C) 2010 Santa Claus'))
     tags.append(ExifTag('Exif.GPSInfo.GPSVersionID', '0'))
     tags.append(ExifTag('Exif.Pentax.Temperature', '14'))
     tags.append(ExifTag('Exif.Photo.UserComment', 'foo bar baz'))
     tags.append(ExifTag('Exif.Image.BitsPerSample', 8))
     tags.append(ExifTag('Exif.Image.TimeZoneOffset', 7))
     tags.append(ExifTag('Exif.Image.ImageWidth', 7492))
     tags.append(ExifTag('Exif.OlympusCs.ManometerReading', 29))
     tags.append(ExifTag('Exif.Image.XResolution', make_fraction(7, 3)))
     tags.append(ExifTag('Exif.Image.BaselineExposure', make_fraction(-7, 3)))
     tags.append(ExifTag('Exif.Photo.ExifVersion', '0100'))
     for tag in tags:
         s = pickle.dumps(tag)
         t = pickle.loads(s)
         self.assert_(isinstance(t, ExifTag))
         self.assertEqual(t.key, tag.key)
         self.assertEqual(t.type, tag.type)
         self.assertEqual(t.name, tag.name)
         self.assertEqual(t.label, tag.label)
         self.assertEqual(t.description, tag.description)
         self.assertEqual(t.section_name, tag.section_name)
         self.assertEqual(t.section_description, tag.section_description)
         self.assertEqual(t.raw_value, tag.raw_value)
         self.assertEqual(t.value, tag.value)
         self.assertEqual(t.human_value, tag.human_value)
Example #2
0
File: xmp.py Project: Namejs/workr
    def test_convert_to_string_rational(self):
        # Valid values
        tag = XmpTag('Xmp.xmpDM.videoPixelAspectRatio')
        self.assertEqual(tag.type, 'Rational')
        self.assertEqual(tag._convert_to_string(make_fraction(5, 3), 'Rational'), '5/3')
        self.assertEqual(tag._convert_to_string(make_fraction(-5, 3), 'Rational'), '-5/3')

        # Invalid values
        self.failUnlessRaises(XmpValueError, tag._convert_to_string, 'invalid', 'Rational')
Example #3
0
File: exif.py Project: Namejs/workr
    def test_convert_to_string_rational(self):
        # Valid values
        tag = ExifTag("Exif.Image.XResolution")
        self.assertEqual(tag.type, "Rational")
        self.assertEqual(tag._convert_to_string(make_fraction(5, 3)), "5/3")

        # Invalid values
        self.failUnlessRaises(ExifValueError, tag._convert_to_string, "invalid")
        self.failUnlessRaises(ExifValueError, tag._convert_to_string, make_fraction(-5, 3))
Example #4
0
    def test_convert_to_string_srational(self):
        # Valid values
        tag = ExifTag('Exif.Image.BaselineExposure')
        self.assertEqual(tag.type, 'SRational')
        self.assertEqual(tag._convert_to_string(make_fraction(5, 3)), '5/3')
        self.assertEqual(tag._convert_to_string(make_fraction(-5, 3)), '-5/3')

        # Invalid values
        self.failUnlessRaises(ExifValueError, tag._convert_to_string, 'invalid')
Example #5
0
File: exif.py Project: Namejs/workr
    def test_convert_to_string_srational(self):
        # Valid values
        tag = ExifTag("Exif.Image.BaselineExposure")
        self.assertEqual(tag.type, "SRational")
        self.assertEqual(tag._convert_to_string(make_fraction(5, 3)), "5/3")
        self.assertEqual(tag._convert_to_string(make_fraction(-5, 3)), "-5/3")

        # Invalid values
        self.failUnlessRaises(ExifValueError, tag._convert_to_string, "invalid")
Example #6
0
    def test_convert_to_string_rational(self):
        # Valid values
        tag = ExifTag('Exif.Image.XResolution')
        self.assertEqual(tag.type, 'Rational')
        self.assertEqual(tag._convert_to_string(make_fraction(5, 3)), '5/3')

        # Invalid values
        self.failUnlessRaises(ExifValueError, tag._convert_to_string, 'invalid')
        self.failUnlessRaises(ExifValueError,
                              tag._convert_to_string, make_fraction(-5, 3))
Example #7
0
    def test_convert_to_string_rational(self):
        # Valid values
        tag = ExifTag('Exif.Image.XResolution')
        self.assertEqual(tag.type, 'Rational')
        self.assertEqual(tag._convert_to_string(make_fraction(5, 3)), '5/3')

        # Invalid values
        self.failUnlessRaises(ExifValueError, tag._convert_to_string,
                              'invalid')
        self.failUnlessRaises(ExifValueError, tag._convert_to_string,
                              make_fraction(-5, 3))
Example #8
0
    def test_convert_to_python_srational(self):
        # Valid values
        tag = ExifTag('Exif.Image.BaselineExposure')
        self.assertEqual(tag.type, 'SRational')
        self.assertEqual(tag._convert_to_python('5/3'), make_fraction(5, 3))
        self.assertEqual(tag._convert_to_python('-5/3'), make_fraction(-5, 3))

        # Invalid values
        self.failUnlessRaises(ExifValueError, tag._convert_to_python,
                              'invalid')
        self.failUnlessRaises(ExifValueError, tag._convert_to_python, '5 / 3')
        self.failUnlessRaises(ExifValueError, tag._convert_to_python, '5/-3')
Example #9
0
    def test_convert_to_string_rational(self):
        # Valid values
        tag = XmpTag('Xmp.xmpDM.videoPixelAspectRatio')
        self.assertEqual(tag.type, 'Rational')
        self.assertEqual(
            tag._convert_to_string(make_fraction(5, 3), 'Rational'), '5/3')
        self.assertEqual(
            tag._convert_to_string(make_fraction(-5, 3), 'Rational'), '-5/3')

        # Invalid values
        self.assertRaises(XmpValueError, tag._convert_to_string, 'invalid',
                          'Rational')
Example #10
0
    def testReadMetadata(self):
        """
        Perform various tests on reading the metadata contained in a file.
        """
        # Check that the reference file is not corrupted
        filename = os.path.join('data', 'smiley1.jpg')
        filepath = testutils.get_absolute_file_path(filename)
        md5sum = 'c066958457c685853293058f9bf129c1'
        self.assertCorrectFile(filepath, md5sum)

        # Read the image metadata
        image = pyexiv2.ImageMetadata(filepath)
        image.read()

        # Exhaustive tests on the values of EXIF metadata
        exifTags = [('Exif.Image.ImageDescription', str,
                     'Well it is a smiley that happens to be green'),
                    ('Exif.Image.XResolution', FRACTION, make_fraction(72, 1)),
                    ('Exif.Image.YResolution', FRACTION, make_fraction(72, 1)),
                    ('Exif.Image.ResolutionUnit', int, 2),
                    ('Exif.Image.Software', str, 'ImageReady'),
                    ('Exif.Image.DateTime', datetime.datetime,
                     datetime.datetime(2004, 7, 13, 21, 23, 44)),
                    ('Exif.Image.Artist', str, 'No one'),
                    ('Exif.Image.Copyright', str, ''),
                    ('Exif.Image.ExifTag', long, 226L),
                    ('Exif.Photo.Flash', int, 80),
                    ('Exif.Photo.PixelXDimension', long, 167L),
                    ('Exif.Photo.PixelYDimension', long, 140L)]
        self.assertEqual(image.exif_keys, [tag[0] for tag in exifTags])
        for key, ktype, value in exifTags:
            self.check_type_and_value(image[key], ktype, value)

        # Exhaustive tests on the values of IPTC metadata
        iptcTags = [('Iptc.Application2.Caption', str,
                     ['yelimS green faced dude (iptc caption)']),
                    ('Iptc.Application2.Writer', str, ['Nobody']),
                    ('Iptc.Application2.Byline', str, ['Its me']),
                    ('Iptc.Application2.ObjectName', str, ['GreeenDude']),
                    ('Iptc.Application2.DateCreated', datetime.date,
                     [datetime.date(2004, 7, 13)]),
                    ('Iptc.Application2.City', str, ['Seattle']),
                    ('Iptc.Application2.ProvinceState', str, ['WA']),
                    ('Iptc.Application2.CountryName', str, ['USA']),
                    ('Iptc.Application2.Category', str, ['Things']),
                    ('Iptc.Application2.Keywords', str,
                     ['Green', 'Smiley', 'Dude']),
                    ('Iptc.Application2.Copyright', str, ['\xa9 2004 Nobody'])]
        self.assertEqual(image.iptc_keys, [tag[0] for tag in iptcTags])
        for key, ktype, values in iptcTags:
            self.check_type_and_values(image[key], ktype, values)
Example #11
0
def add_exif_using_timestamp(filename,
                             time,
                             points,
                             offset_time=0,
                             offset_angle=0):
    '''
    Find lat, lon and bearing of filename and write to EXIF.
    '''

    metadata = pyexiv2.ImageMetadata(filename)
    metadata.read()

    # subtract offset in s beween gpx time and exif time
    t = time - datetime.timedelta(seconds=offset_time)

    try:
        lat, lon, bearing, elevation, speed = interpolate_lat_lon(points, t)

        lat_deg = decimal_to_dms(lat, ["S", "N"])
        lon_deg = decimal_to_dms(lon, ["W", "E"])

        # convert decimal coordinates into degrees, minutes and seconds as fractions for EXIF
        exiv_lat = (make_fraction(lat_deg[0],
                                  1), make_fraction(int(lat_deg[1]), 1),
                    make_fraction(int(lat_deg[2] * 1000000), 1000000))
        exiv_lon = (make_fraction(lon_deg[0],
                                  1), make_fraction(int(lon_deg[1]), 1),
                    make_fraction(int(lon_deg[2] * 1000000), 1000000))

        # convert direction into fraction
        bearing = offset_bearing(bearing, offset_angle)
        exiv_bearing = make_fraction(int(bearing * 100), 100)

        # add to exif
        metadata["Exif.GPSInfo.GPSLatitude"] = exiv_lat
        metadata["Exif.GPSInfo.GPSLatitudeRef"] = lat_deg[3]
        metadata["Exif.GPSInfo.GPSLongitude"] = exiv_lon
        metadata["Exif.GPSInfo.GPSLongitudeRef"] = lon_deg[3]
        metadata["Exif.Image.GPSTag"] = 654
        metadata["Exif.GPSInfo.GPSMapDatum"] = "WGS-84"
        metadata["Exif.GPSInfo.GPSVersionID"] = '2 0 0 0'
        metadata["Exif.GPSInfo.GPSImgDirection"] = exiv_bearing
        metadata["Exif.GPSInfo.GPSImgDirectionRef"] = "T"

        if elevation is not None:
            exiv_elevation = make_fraction(abs(int(elevation * 10)), 10)
            metadata["Exif.GPSInfo.GPSAltitude"] = exiv_elevation
            metadata[
                "Exif.GPSInfo.GPSAltitudeRef"] = '0' if elevation >= 0 else '1'

        metadata.write()
        print("Added geodata to {}: {}, {:.6f}, {:.6f}, {:.1f}".format(
            os.path.basename(filename), time, lat, lon, bearing))

        if (speed is not None and speed < 0.6):
            move_into_dir(filename, os.path.dirname(filename) + "\S0")

    except ValueError, e:
        print("Skipping {0}: {1}".format(filename, e))
Example #12
0
 def test_setitem(self):
     self.metadata.read()
     # Set new tags
     key = 'Exif.Photo.ExposureBiasValue'
     tag = ExifTag(key, make_fraction(0, 3))
     self.metadata[key] = tag
     self.failUnless(key in self.metadata._tags['exif'])
     self.failUnlessEqual(self.metadata._tags['exif'][key], tag)
     key = 'Iptc.Application2.City'
     tag = IptcTag(key, ['Barcelona'])
     self.metadata[key] = tag
     self.failUnless(key in self.metadata._tags['iptc'])
     self.failUnlessEqual(self.metadata._tags['iptc'][key], tag)
     key = 'Xmp.dc.description'
     tag = XmpTag(key, {'x-default': 'Sunset picture.'})
     self.metadata[key] = tag
     self.failUnless(key in self.metadata._tags['xmp'])
     self.failUnlessEqual(self.metadata._tags['xmp'][key], tag)
     # Replace existing tags
     key = 'Exif.Photo.ExifVersion'
     tag = ExifTag(key, '0220')
     self.metadata[key] = tag
     self.failUnless(key in self.metadata._tags['exif'])
     self.failUnlessEqual(self.metadata._tags['exif'][key], tag)
     key = 'Iptc.Application2.Caption'
     tag = IptcTag(key, ['Sunset on Barcelona.'])
     self.metadata[key] = tag
     self.failUnless(key in self.metadata._tags['iptc'])
     self.failUnlessEqual(self.metadata._tags['iptc'][key], tag)
     key = 'Xmp.dc.subject'
     tag = XmpTag(key, ['sunset', 'Barcelona', 'beautiful', 'beach'])
     self.metadata[key] = tag
     self.failUnless(key in self.metadata._tags['xmp'])
     self.failUnlessEqual(self.metadata._tags['xmp'][key], tag)
Example #13
0
def test_setitem(metadata_ro):
    m = metadata_ro.metadata
    m.read()
    # Set new tags
    key = 'Exif.Photo.ExposureBiasValue'
    tag = ExifTag(key, make_fraction(0, 3))
    m[key] = tag
    assert key in m._tags['exif']
    assert m._tags['exif'][key] == tag
    key = 'Iptc.Application2.City'
    tag = IptcTag(key, ['Barcelona'])
    m[key] = tag
    assert key in m._tags['iptc']
    assert m._tags['iptc'][key] == tag
    key = 'Xmp.dc.description'
    tag = XmpTag(key, {'x-default': 'Sunset picture.'})
    m[key] = tag
    assert key in m._tags['xmp']
    assert m._tags['xmp'][key] == tag
    # Replace existing tags
    key = 'Exif.Photo.ExifVersion'
    tag = ExifTag(key, '0220')
    m[key] = tag
    assert key in m._tags['exif']
    assert m._tags['exif'][key] == tag
    key = 'Iptc.Application2.Caption'
    tag = IptcTag(key, ['Sunset on Barcelona.'])
    m[key] = tag
    assert key in m._tags['iptc']
    assert m._tags['iptc'][key] == tag
    key = 'Xmp.dc.subject'
    tag = XmpTag(key, ['sunset', 'Barcelona', 'beautiful', 'beach'])
    m[key] = tag
    assert key in m._tags['xmp']
    assert m._tags['xmp'][key] == tag
Example #14
0
    def test_convert_to_python_rational(self):
        # Valid values
        tag = XmpTag('Xmp.xmpDM.videoPixelAspectRatio')
        self.assertEqual(tag.type, 'Rational')
        self.assertEqual(tag._convert_to_python('5/3', 'Rational'),
                         make_fraction(5, 3))
        self.assertEqual(tag._convert_to_python('-5/3', 'Rational'),
                         make_fraction(-5, 3))

        # Invalid values
        self.failUnlessRaises(XmpValueError, tag._convert_to_python, 'invalid',
                              'Rational')
        self.failUnlessRaises(XmpValueError, tag._convert_to_python, '5 / 3',
                              'Rational')
        self.failUnlessRaises(XmpValueError, tag._convert_to_python, '5/-3',
                              'Rational')
Example #15
0
 def test_setitem(self):
     self.metadata.read()
     # Set new tags
     key = 'Exif.Photo.ExposureBiasValue'
     tag = ExifTag(key, make_fraction(0, 3))
     self.metadata[key] = tag
     self.failUnless(key in self.metadata._tags['exif'])
     self.failUnlessEqual(self.metadata._tags['exif'][key], tag)
     key = 'Iptc.Application2.City'
     tag = IptcTag(key, ['Barcelona'])
     self.metadata[key] = tag
     self.failUnless(key in self.metadata._tags['iptc'])
     self.failUnlessEqual(self.metadata._tags['iptc'][key], tag)
     key = 'Xmp.dc.description'
     tag = XmpTag(key, {'x-default': 'Sunset picture.'})
     self.metadata[key] = tag
     self.failUnless(key in self.metadata._tags['xmp'])
     self.failUnlessEqual(self.metadata._tags['xmp'][key], tag)
     # Replace existing tags
     key = 'Exif.Photo.ExifVersion'
     tag = ExifTag(key, '0220')
     self.metadata[key] = tag
     self.failUnless(key in self.metadata._tags['exif'])
     self.failUnlessEqual(self.metadata._tags['exif'][key], tag)
     key = 'Iptc.Application2.Caption'
     tag = IptcTag(key, ['Sunset on Barcelona.'])
     self.metadata[key] = tag
     self.failUnless(key in self.metadata._tags['iptc'])
     self.failUnlessEqual(self.metadata._tags['iptc'][key], tag)
     key = 'Xmp.dc.subject'
     tag = XmpTag(key, ['sunset', 'Barcelona', 'beautiful', 'beach'])
     self.metadata[key] = tag
     self.failUnless(key in self.metadata._tags['xmp'])
     self.failUnlessEqual(self.metadata._tags['xmp'][key], tag)
Example #16
0
    def testReadMetadata(self):
        """
        Perform various tests on reading the metadata contained in a file.
        """
        # Check that the reference file is not corrupted
        filename = os.path.join('data', 'smiley1.jpg')
        filepath = testutils.get_absolute_file_path(filename)
        md5sum = 'c066958457c685853293058f9bf129c1'
        self.assertCorrectFile(filepath, md5sum)

        # Read the image metadata
        image = pyexiv2.ImageMetadata(filepath)
        image.read()

        # Exhaustive tests on the values of EXIF metadata
        exifTags = [('Exif.Image.ImageDescription', str, 'Well it is a smiley that happens to be green'),
                    ('Exif.Image.XResolution', FRACTION, make_fraction(72, 1)),
                    ('Exif.Image.YResolution', FRACTION, make_fraction(72, 1)),
                    ('Exif.Image.ResolutionUnit', int, 2),
                    ('Exif.Image.Software', str, 'ImageReady'),
                    ('Exif.Image.DateTime', datetime.datetime, datetime.datetime(2004, 7, 13, 21, 23, 44)),
                    ('Exif.Image.Artist', str, 'No one'),
                    ('Exif.Image.Copyright', str, ''),
                    ('Exif.Image.ExifTag', long, 226L),
                    ('Exif.Photo.Flash', int, 80),
                    ('Exif.Photo.PixelXDimension', long, 167L),
                    ('Exif.Photo.PixelYDimension', long, 140L)]
        self.assertEqual(image.exif_keys, [tag[0] for tag in exifTags])
        for key, ktype, value in exifTags:
            self.check_type_and_value(image[key], ktype, value)

        # Exhaustive tests on the values of IPTC metadata
        iptcTags = [('Iptc.Application2.Caption', str, ['yelimS green faced dude (iptc caption)']),
                    ('Iptc.Application2.Writer', str, ['Nobody']),
                    ('Iptc.Application2.Byline', str, ['Its me']),
                    ('Iptc.Application2.ObjectName', str, ['GreeenDude']),
                    ('Iptc.Application2.DateCreated', datetime.date, [datetime.date(2004, 7, 13)]),
                    ('Iptc.Application2.City', str, ['Seattle']),
                    ('Iptc.Application2.ProvinceState', str, ['WA']),
                    ('Iptc.Application2.CountryName', str, ['USA']),
                    ('Iptc.Application2.Category', str, ['Things']),
                    ('Iptc.Application2.Keywords', str, ['Green', 'Smiley', 'Dude']),
                    ('Iptc.Application2.Copyright', str, ['\xa9 2004 Nobody'])]
        self.assertEqual(image.iptc_keys, [tag[0] for tag in iptcTags])
        for key, ktype, values in iptcTags:
            self.check_type_and_values(image[key], ktype, values)
Example #17
0
def add_gps_to_exif(
    filename,
    lat,
    lon,
    bearing,
    elevation,
    updated_filename=None,
    remove_image_description=True,
):
    """
    Given lat, lon, bearing, elevation, write to EXIF
    """
    # TODO: use this within add_exif_using_timestamp
    if updated_filename is not None:
        shutil.copy2(filename, updated_filename)
        filename = updated_filename

    metadata = pyexiv2.ImageMetadata(filename)
    metadata.read()
    lat_deg = to_deg(lat, ["S", "N"])
    lon_deg = to_deg(lon, ["W", "E"])

    # convert decimal coordinates into degrees, minutes and seconds as fractions for EXIF
    exiv_lat = (
        make_fraction(lat_deg[0], 1),
        make_fraction(int(lat_deg[1]), 1),
        make_fraction(int(lat_deg[2] * 1000000), 1000000),
    )
    exiv_lon = (
        make_fraction(lon_deg[0], 1),
        make_fraction(int(lon_deg[1]), 1),
        make_fraction(int(lon_deg[2] * 1000000), 1000000),
    )

    # convert direction into fraction
    exiv_bearing = make_fraction(int(bearing * 100), 100)

    # add to exif
    metadata["Exif.GPSInfo.GPSLatitude"] = exiv_lat
    metadata["Exif.GPSInfo.GPSLatitudeRef"] = lat_deg[3]
    metadata["Exif.GPSInfo.GPSLongitude"] = exiv_lon
    metadata["Exif.GPSInfo.GPSLongitudeRef"] = lon_deg[3]
    metadata["Exif.Image.GPSTag"] = 654
    metadata["Exif.GPSInfo.GPSMapDatum"] = "WGS-84"
    metadata["Exif.GPSInfo.GPSVersionID"] = "2 0 0 0"
    metadata["Exif.GPSInfo.GPSImgDirection"] = exiv_bearing
    metadata["Exif.GPSInfo.GPSImgDirectionRef"] = "T"
    if remove_image_description:
        metadata["Exif.Image.ImageDescription"] = []

    if elevation is not None:
        exiv_elevation = make_fraction(int(abs(elevation) * 100), 100)
        metadata["Exif.GPSInfo.GPSAltitude"] = exiv_elevation
        metadata[
            "Exif.GPSInfo.GPSAltitudeRef"] = "0" if elevation >= 0 else "1"
    metadata.write()
def add_exif_using_timestamp(filename, points, offset_time=0):
    '''
    Find lat, lon and bearing of filename and write to EXIF.
    '''

    metadata = pyexiv2.ImageMetadata(filename)
    metadata.read()
    t = metadata['Exif.Photo.DateTimeOriginal'].value
    try:
        t_subsec = metadata['Exif.Photo.SubSecTimeOriginal'].value
        t_subsec_delta = datetime.timedelta(seconds=float("0."+t_subsec))
        t += t_subsec_delta
    except KeyError:
        pass


    # subtract offset in s beween gpx time and exif time
    t = t - datetime.timedelta(seconds=offset_time)

    try:
        lat, lon, bearing, elevation = interpolate_lat_lon(points, t)

        lat_deg = to_deg(lat, ["S", "N"])
        lon_deg = to_deg(lon, ["W", "E"])

        # convert decimal coordinates into degrees, minutes and seconds as fractions for EXIF
        exiv_lat = (make_fraction(lat_deg[0],1), make_fraction(int(lat_deg[1]),1), make_fraction(int(lat_deg[2]*1000000),1000000))
        exiv_lon = (make_fraction(lon_deg[0],1), make_fraction(int(lon_deg[1]),1), make_fraction(int(lon_deg[2]*1000000),1000000))

        # convert direction into fraction
        exiv_bearing = make_fraction(int(bearing*100),100)

        # add to exif
        metadata["Exif.GPSInfo.GPSLatitude"] = exiv_lat
        metadata["Exif.GPSInfo.GPSLatitudeRef"] = lat_deg[3]
        metadata["Exif.GPSInfo.GPSLongitude"] = exiv_lon
        metadata["Exif.GPSInfo.GPSLongitudeRef"] = lon_deg[3]
        metadata["Exif.Image.GPSTag"] = 654
        metadata["Exif.GPSInfo.GPSMapDatum"] = "WGS-84"
        metadata["Exif.GPSInfo.GPSVersionID"] = '2 0 0 0'
        metadata["Exif.GPSInfo.GPSImgDirection"] = exiv_bearing
        metadata["Exif.GPSInfo.GPSImgDirectionRef"] = "T"

        if elevation is not None:
            exiv_elevation = make_fraction(abs(int(elevation*10)),10)
            metadata["Exif.GPSInfo.GPSAltitude"] = exiv_elevation
            metadata["Exif.GPSInfo.GPSAltitudeRef"] = '0' if elevation >= 0 else '1'
        try:
            metadata.write()
            print("Added geodata to: {0} ({1}, {2}, {3}), altitude {4}".format(filename, lat, lon, bearing, elevation))
        except IOError:
            print("Failed writing to: {0}".format(filename))

    except ValueError, e:
        print("Skipping {0}: {1}".format(filename, e))
Example #19
0
    def test_make_fraction(self):
        if Fraction is not None:
            self.assertEqual(make_fraction(3, 5), Fraction(3, 5))
            self.assertEqual(make_fraction(-3, 5), Fraction(-3, 5))
            self.assertEqual(make_fraction('3/2'), Fraction(3, 2))
            self.assertEqual(make_fraction('-3/4'), Fraction(-3, 4))
            self.assertEqual(make_fraction('0/0'), Fraction(0, 1))
        else:
            self.assertEqual(make_fraction(3, 5), Rational(3, 5))
            self.assertEqual(make_fraction(-3, 5), Rational(-3, 5))
            self.assertEqual(make_fraction('3/2'), Rational(3, 2))
            self.assertEqual(make_fraction('-3/4'), Rational(-3, 4))
            self.assertEqual(make_fraction('0/0'), Rational(0, 1))

        self.assertRaises(ZeroDivisionError, make_fraction, 3, 0)
        self.assertRaises(ZeroDivisionError, make_fraction, '3/0')
        self.assertRaises(TypeError, make_fraction, 5, 3, 2)
        self.assertRaises(TypeError, make_fraction, None)
Example #20
0
    def test_make_fraction(self):
        if Fraction is not None:
            self.assertEqual(make_fraction(3, 5), Fraction(3, 5))
            self.assertEqual(make_fraction(-3, 5), Fraction(-3, 5))
            self.assertEqual(make_fraction('3/2'), Fraction(3, 2))
            self.assertEqual(make_fraction('-3/4'), Fraction(-3, 4))
            self.assertEqual(make_fraction('0/0'), Fraction(0, 1))
        else:
            self.assertEqual(make_fraction(3, 5), Rational(3, 5))
            self.assertEqual(make_fraction(-3, 5), Rational(-3, 5))
            self.assertEqual(make_fraction('3/2'), Rational(3, 2))
            self.assertEqual(make_fraction('-3/4'), Rational(-3, 4))
            self.assertEqual(make_fraction('0/0'), Rational(0, 1))

        self.assertRaises(ZeroDivisionError, make_fraction, 3, 0)
        self.assertRaises(ZeroDivisionError, make_fraction, '3/0')
        self.assertRaises(TypeError, make_fraction, 5, 3, 2)
        self.assertRaises(TypeError, make_fraction, None)
Example #21
0
def add_exif_using_timestamp(filename, points, offset_time=0, timestamp=None, orientation=1, image_description=None):
    '''
    Find lat, lon and bearing of filename and write to EXIF.
    '''

    metadata = pyexiv2.ImageMetadata(filename)
    metadata.read()
    if timestamp:
        metadata['Exif.Photo.DateTimeOriginal'] = timestamp

    t = metadata['Exif.Photo.DateTimeOriginal'].value

    # subtract offset in s beween gpx time and exif time
    t = t - datetime.timedelta(seconds=offset_time)

    try:
        lat, lon, bearing, elevation = interpolate_lat_lon(points, t)

        lat_deg = to_deg(lat, ["S", "N"])
        lon_deg = to_deg(lon, ["W", "E"])

        # convert decimal coordinates into degrees, minutes and seconds as fractions for EXIF
        exiv_lat = (make_fraction(lat_deg[0],1), make_fraction(int(lat_deg[1]),1), make_fraction(int(lat_deg[2]*1000000),1000000))
        exiv_lon = (make_fraction(lon_deg[0],1), make_fraction(int(lon_deg[1]),1), make_fraction(int(lon_deg[2]*1000000),1000000))

        # convert direction into fraction
        exiv_bearing = make_fraction(int(bearing*1000),1000)

        # add to exif
        metadata["Exif.GPSInfo.GPSLatitude"] = exiv_lat
        metadata["Exif.GPSInfo.GPSLatitudeRef"] = lat_deg[3]
        metadata["Exif.GPSInfo.GPSLongitude"] = exiv_lon
        metadata["Exif.GPSInfo.GPSLongitudeRef"] = lon_deg[3]
        metadata["Exif.Image.GPSTag"] = 654
        metadata["Exif.GPSInfo.GPSMapDatum"] = "WGS-84"
        metadata["Exif.GPSInfo.GPSVersionID"] = '2 0 0 0'
        metadata["Exif.GPSInfo.GPSImgDirection"] = exiv_bearing
        metadata["Exif.GPSInfo.GPSImgDirectionRef"] = "T"
        metadata["Exif.Image.Orientation"] = orientation
        if image_description is not None:
            metadata["Exif.Image.ImageDescription"] = image_description

        if elevation is not None:
            exiv_elevation = make_fraction(int(abs(elevation)*100),100)
            metadata["Exif.GPSInfo.GPSAltitude"] = exiv_elevation
            metadata["Exif.GPSInfo.GPSAltitudeRef"] = '0' if elevation >= 0 else '1'

        metadata.write()

        print("Added geodata to: {0} ({1}, {2}, {3}), altitude {4}".format(filename, lat, lon, bearing, elevation))
    except ValueError as e:
        print("Skipping {0}: {1}".format(filename, e))
Example #22
0
File: exif.py Project: Namejs/workr
    def test_convert_to_python_rational(self):
        # Valid values
        tag = ExifTag("Exif.Image.XResolution")
        self.assertEqual(tag.type, "Rational")
        self.assertEqual(tag._convert_to_python("5/3"), make_fraction(5, 3))

        # Invalid values
        self.failUnlessRaises(ExifValueError, tag._convert_to_python, "invalid")
        self.failUnlessRaises(ExifValueError, tag._convert_to_python, "-5/3")
        self.failUnlessRaises(ExifValueError, tag._convert_to_python, "5 / 3")
        self.failUnlessRaises(ExifValueError, tag._convert_to_python, "5/-3")
Example #23
0
    def test_convert_to_python_rational(self):
        # Valid values
        tag = ExifTag('Exif.Image.XResolution')
        self.assertEqual(tag.type, 'Rational')
        self.assertEqual(tag._convert_to_python('5/3'), make_fraction(5, 3))

        # Invalid values
        self.failUnlessRaises(ExifValueError, tag._convert_to_python, 'invalid')
        self.failUnlessRaises(ExifValueError, tag._convert_to_python, '-5/3')
        self.failUnlessRaises(ExifValueError, tag._convert_to_python, '5 / 3')
        self.failUnlessRaises(ExifValueError, tag._convert_to_python, '5/-3')
Example #24
0
    def test_convert_to_python_rational(self):
        # Valid values
        tag = ExifTag('Exif.Image.XResolution')
        self.assertEqual(tag.type, 'Rational')
        self.assertEqual(tag._convert_to_python('5/3'), make_fraction(5, 3))

        # Invalid values
        self.failUnlessRaises(ExifValueError, tag._convert_to_python,
                              'invalid')
        self.failUnlessRaises(ExifValueError, tag._convert_to_python, '-5/3')
        self.failUnlessRaises(ExifValueError, tag._convert_to_python, '5 / 3')
        self.failUnlessRaises(ExifValueError, tag._convert_to_python, '5/-3')
Example #25
0
def add_exif_using_timestamp(filename, time, points, offset_time=0, offset_bearing=0):
    '''
    Find lat, lon and bearing of filename and write to EXIF.
    '''

    metadata = pyexiv2.ImageMetadata(filename)
    metadata.read()
    print(time)
    print(datetime.timedelta(seconds=offset_time))
    #print(points)

    
    # subtract offset in s beween gpx time and exif time
    t = time - datetime.timedelta(seconds=offset_time)

    try:
        lat, lon, bearing, elevation = interpolate_lat_lon(points, t)

        lat_deg = decimal_to_dms(lat, ["S", "N"])
        lon_deg = decimal_to_dms(lon, ["W", "E"])

        # convert decimal coordinates into degrees, minutes and seconds as fractions for EXIF
        exiv_lat = (make_fraction(lat_deg[0],1), make_fraction(int(lat_deg[1]),1), make_fraction(int(lat_deg[2]*1000000),1000000))
        exiv_lon = (make_fraction(lon_deg[0],1), make_fraction(int(lon_deg[1]),1), make_fraction(int(lon_deg[2]*1000000),1000000))

        corrected_bearing = (bearing + offset_bearing) % 360

        # convert direction into fraction
        exiv_bearing = make_fraction(int(corrected_bearing*100),100)

        # add to exif
        metadata["Exif.GPSInfo.GPSLatitude"] = exiv_lat
        metadata["Exif.GPSInfo.GPSLatitudeRef"] = lat_deg[3]
        metadata["Exif.GPSInfo.GPSLongitude"] = exiv_lon
        metadata["Exif.GPSInfo.GPSLongitudeRef"] = lon_deg[3]
        metadata["Exif.Image.GPSTag"] = 654
        metadata["Exif.GPSInfo.GPSMapDatum"] = "WGS-84"
        metadata["Exif.GPSInfo.GPSVersionID"] = '2 0 0 0'
        metadata["Exif.GPSInfo.GPSImgDirection"] = exiv_bearing
        metadata["Exif.GPSInfo.GPSImgDirectionRef"] = "T"

        if elevation is not None:
            exiv_elevation = make_fraction(abs(int(elevation*10)),10)
            metadata["Exif.GPSInfo.GPSAltitude"] = exiv_elevation
            metadata["Exif.GPSInfo.GPSAltitudeRef"] = '0' if elevation >= 0 else '1'

        metadata.write()
        print("Added geodata to: {}  time {}  lat {}  lon {}  alt {}  bearing {}".format(filename, time, lat, lon, elevation, exiv_bearing))
    except ValueError, e:
        print("Skipping {0}: {1}".format(filename, e))
Example #26
0
    def add_lat_lon(self, lat, lon, precision=1000000):
        ''' Add lat, lon to gps (lat, lon in float)
        @source: originally from geotag_from_gpx.py
        '''

        # convert decimal coordinates into degrees, minutes and seconds
        lat_deg = decimal_to_dms(lat, ["S", "N"])
        lon_deg = decimal_to_dms(lon, ["W", "E"])

        # convert degrees, minutes and seconds as fractions for EXIF
        exiv_lat = (make_fraction(lat_deg[0],
                                  1), make_fraction(int(lat_deg[1]), 1),
                    make_fraction(int(lat_deg[2] * precision), precision))
        exiv_lon = (make_fraction(lon_deg[0],
                                  1), make_fraction(int(lon_deg[1]), 1),
                    make_fraction(int(lon_deg[2] * precision), precision))

        # add to exif
        self.metadata["Exif.GPSInfo.GPSLatitude"] = exiv_lat
        self.metadata["Exif.GPSInfo.GPSLatitudeRef"] = lat_deg[3]
        self.metadata["Exif.GPSInfo.GPSLongitude"] = exiv_lon
        self.metadata["Exif.GPSInfo.GPSLongitudeRef"] = lon_deg[3]
        self.metadata["Exif.Image.GPSTag"] = 654
        self.metadata["Exif.GPSInfo.GPSMapDatum"] = "WGS-84"
        self.metadata["Exif.GPSInfo.GPSVersionID"] = '2 0 0 0'
Example #27
0
    def testReadMetadata(self):
        """
        Perform various tests on reading the metadata contained in a file.
        """
        # Check that the reference file is not corrupted
        filename = os.path.join('data', 'DSCF_0273.JPG')
        filepath = testutils.get_absolute_file_path(filename)
        md5sum = '64d4b7eab1e78f1f6bfb3c966e99eef2'
        #self.assertCorrectFile(filepath, md5sum)

        # Read the image metadata
        image = pyexiv2.ImageMetadata(filepath)
        image.read()

        # Exhaustive tests on the values of EXIF metadata
        exifTags = [('Exif.Image.Software', str, 'Digital Camera FinePix S4800 Ver1.00'),
                    ('Exif.Image.XResolution', FRACTION, make_fraction(72, 1)),
                    ('Exif.Image.YResolution', FRACTION, make_fraction(72, 1)),
                    ('Exif.Image.ResolutionUnit', int, 2),
                    ('Exif.Image.Software', str, 'Digital Camera FinePix S4800 Ver1.00'),
                    ('Exif.Image.DateTime', datetime.datetime, datetime.datetime(2015, 1, 17, 13, 53, 3)),
                    ('Exif.Image.Artist', str, 'Vincent Vande Vyvre'),
                    ('Exif.Photo.ApertureValue', FRACTION, make_fraction(6, 1)),
                    ('Exif.Photo.FNumber', FRACTION, make_fraction(8, 1)),
                    ('Exif.Photo.PixelXDimension', int, 250),
                    ('Exif.Photo.PixelYDimension', int, 140)]
        for key, ktype, value in exifTags:
            self.check_type_and_value(image[key], ktype, value)

        # Exhaustive tests on the values of IPTC metadata
        iptcTags = [('Iptc.Application2.Caption', str, ['S']),
                    ('Iptc.Application2.Byline', str, ['Vincent Vande Vyvre']),
                    ('Iptc.Application2.0x00d7', str, ['www.oqapy.eu']),
                    ('Iptc.Application2.Keywords', str, ['bruxelles botanique']),
                    ('Iptc.Application2.Copyright', str, ['2013 Vincent Vande Vyvre'])]
        for key, ktype, values in iptcTags:
            self.check_type_and_values(image[key], ktype, values)
def write_direction_to_image(filename, direction):
    ''' 
    Write the direction to the exif tag of the photograph.
    @param filename: photograph filename
    @param direction: direction of view in degrees
    '''
    metadata = pyexiv2.ImageMetadata(filename)
    metadata.read()

    exiv_direction = make_fraction(int(direction * 10), 10)
    try:
        metadata["Exif.GPSInfo.GPSImgDirection"] = exiv_direction
        metadata["Exif.GPSInfo.GPSImgDirectionRef"] = "T"
        metadata.write()
        print("Added direction to: {0} ({1} degrees)".format(filename, float(exiv_direction)))
    except ValueError, e:
        print("Skipping {0}: {1}".format(filename, e))
    def set_gps_exif(self, file_name, lat, lon, alt):
        """Adds GPS position as EXIF metadata
        file_name -- image file
        lat -- latitude (1e7 deg, as int)
        lon -- longitude (1e7 deg, as int)
        alt -- altitude MSL (in mm, as int)
        """
        def get_loc(value, loc):
            if value < 0:
                return loc[0]
            elif value > 0:
                return loc[1]
            else:
                return ""

        try:
            exiv_lat = (make_fraction(abs(lat), 10000000), make_fraction(0, 1),
                        make_fraction(0, 1))
            exiv_lng = (make_fraction(abs(lon), 10000000), make_fraction(0, 1),
                        make_fraction(0, 1))
            if alt > 0.:
                exiv_alt = make_fraction(alt, 1000)
            else:
                exiv_alt = make_fraction(0, 1)

            exiv_image = pyexiv2.ImageMetadata(file_name)
            exiv_image.read()
            exiv_image["Exif.GPSInfo.GPSLatitude"] = exiv_lat
            exiv_image["Exif.GPSInfo.GPSLatitudeRef"] = get_loc(
                lat, ["S", "N"])
            exiv_image["Exif.GPSInfo.GPSLongitude"] = exiv_lng
            exiv_image["Exif.GPSInfo.GPSLongitudeRef"] = get_loc(
                lon, ["W", "E"])
            exiv_image["Exif.GPSInfo.GPSAltitude"] = exiv_alt
            exiv_image["Exif.GPSInfo.GPSAltitudeRef"] = '0'
            exiv_image["Exif.Image.GPSTag"] = 654
            exiv_image["Exif.GPSInfo.GPSMapDatum"] = "WGS-84"
            exiv_image["Exif.GPSInfo.GPSVersionID"] = '2 0 0 0'
            exiv_image.write()
            self.verbose_print("writing exif done")
        except:
            self.verbose_print("writing exif failed")
            pass
Example #30
0
def write_newpos_to_image(filename, coordinate):
    '''
    Write the new position to the exif tag of the picture.
    @param filename: picture filename
    @param coordinate: coordinate (details)
    '''
    metadata = pyexiv2.ImageMetadata(filename)
    metadata.read()

    exiv_direction = make_fraction(int(direction * 10), 10)
    try:
        metadata["Exif.GPSInfo.GPSImgDirection"] = exiv_direction
        metadata["Exif.GPSInfo.GPSImgDirectionRef"] = "T"
        metadata.write()
        print("Added direction to: {0} ({1} degrees)".format(
            filename, float(exiv_direction)))
    except ValueError, e:
        print("Skipping {0}: {1}".format(filename, e))
Example #31
0
def write_direction_to_image(filename, direction):
    ''' 
    Write the direction to the exif tag of the photograph.
    @param filename: photograph filename
    @param direction: direction of view in degrees
    '''
    metadata = pyexiv2.ImageMetadata(filename)
    metadata.read()

    exiv_direction = make_fraction(int(direction * 10), 10)
    try:
        metadata["Exif.GPSInfo.GPSImgDirection"] = exiv_direction
        metadata["Exif.GPSInfo.GPSImgDirectionRef"] = "T"
        metadata.write()
        print("Added direction to: {0} ({1} degrees)".format(
            filename, float(exiv_direction)))
    except ValueError, e:
        print("Skipping {0}: {1}".format(filename, e))
def add_coord_into_exif(filename, lat, lon,bearing):
    '''
    Find lat, lon and bearing of filename and write to EXIF.
    '''


    metadata = pyexiv2.ImageMetadata(filename)
    metadata.read()
    #print(metadata)


    try:

        #t = metadata['Exif.Photo.DateTimeOriginal'].value


        bearing=round(float(bearing))

        lat_deg = to_deg(float(lat), ["S", "N"])
        lon_deg = to_deg(float(lon), ["W", "E"])

        # convert decimal coordinates into degrees, minutes and seconds as fractions for EXIF
        exiv_lat = (make_fraction(lat_deg[0],1), make_fraction(int(lat_deg[1]),1), make_fraction(int(lat_deg[2]*1000000),1000000))
        exiv_lon = (make_fraction(lon_deg[0],1), make_fraction(int(lon_deg[1]),1), make_fraction(int(lon_deg[2]*1000000),1000000))

        # convert direction into fraction
        exiv_bearing = make_fraction(int(bearing*100),100)

        # add to exif
        metadata["Exif.GPSInfo.GPSLatitude"] = exiv_lat
        metadata["Exif.GPSInfo.GPSLatitudeRef"] = lat_deg[3]
        metadata["Exif.GPSInfo.GPSLongitude"] = exiv_lon
        metadata["Exif.GPSInfo.GPSLongitudeRef"] = lon_deg[3]
        metadata["Exif.Image.GPSTag"] = 654
        metadata["Exif.GPSInfo.GPSMapDatum"] = "WGS-84"
        metadata["Exif.GPSInfo.GPSVersionID"] = '2 0 0 0'
        metadata["Exif.GPSInfo.GPSImgDirection"] = exiv_bearing
        metadata["Exif.GPSInfo.GPSImgDirectionRef"] = "T"


        metadata.write()
        #print("Added geodata to: {0} ({1}, {2}, {3})".format(filename, lat, lon, bearing))
    except ValueError, e:
        print("Skipping {0}: {1}".format(filename, e))
Example #33
0
def add_gps_to_exif(filename, lat, lon, bearing, elevation, updated_filename=None, remove_image_description=True):
    '''
    Given lat, lon, bearing, elevation, write to EXIF
    '''
    # TODO: use this within add_exif_using_timestamp
    if updated_filename is not None:
        shutil.copy2(filename, updated_filename)
        filename = updated_filename

    metadata = pyexiv2.ImageMetadata(filename)
    metadata.read()
    lat_deg = to_deg(lat, ["S", "N"])
    lon_deg = to_deg(lon, ["W", "E"])

    # convert decimal coordinates into degrees, minutes and seconds as fractions for EXIF
    exiv_lat = (make_fraction(lat_deg[0],1), make_fraction(int(lat_deg[1]),1), make_fraction(int(lat_deg[2]*1000000),1000000))
    exiv_lon = (make_fraction(lon_deg[0],1), make_fraction(int(lon_deg[1]),1), make_fraction(int(lon_deg[2]*1000000),1000000))

    # convert direction into fraction
    exiv_bearing = make_fraction(int(bearing*100),100)

    # add to exif
    metadata["Exif.GPSInfo.GPSLatitude"] = exiv_lat
    metadata["Exif.GPSInfo.GPSLatitudeRef"] = lat_deg[3]
    metadata["Exif.GPSInfo.GPSLongitude"] = exiv_lon
    metadata["Exif.GPSInfo.GPSLongitudeRef"] = lon_deg[3]
    metadata["Exif.Image.GPSTag"] = 654
    metadata["Exif.GPSInfo.GPSMapDatum"] = "WGS-84"
    metadata["Exif.GPSInfo.GPSVersionID"] = '2 0 0 0'
    metadata["Exif.GPSInfo.GPSImgDirection"] = exiv_bearing
    metadata["Exif.GPSInfo.GPSImgDirectionRef"] = "T"
    if remove_image_description: metadata["Exif.Image.ImageDescription"] = []

    if elevation is not None:
        exiv_elevation = make_fraction(int(abs(elevation)*100),100)
        metadata["Exif.GPSInfo.GPSAltitude"] = exiv_elevation
        metadata["Exif.GPSInfo.GPSAltitudeRef"] = '0' if elevation >= 0 else '1'
    metadata.write()
Example #34
0
 def test_pickle_xmp_tag(self):
     tags = []
     tags.append(XmpTag('Xmp.dc.subject', ['foo', 'bar', 'baz']))
     tags.append(XmpTag('Xmp.xmpRights.Marked', True))
     tags.append(XmpTag('Xmp.xmp.CreateDate', datetime.date.today()))
     tags.append(XmpTag('Xmp.xmpMM.SaveID', 34))
     tags.append(XmpTag('Xmp.dc.format', ('image', 'jpeg')))
     tags.append(XmpTag('Xmp.photoshop.CaptionWriter', 'John Doe'))
     tags.append(XmpTag('Xmp.dc.source', 'bleh'))
     tags.append(XmpTag('Xmp.xmpMM.DocumentID', 'http://example.com'))
     tags.append(XmpTag('Xmp.xmp.BaseURL', 'http://example.com'))
     tags.append(XmpTag('Xmp.xmpDM.videoPixelAspectRatio', make_fraction(5, 3)))
     for tag in tags:
         s = pickle.dumps(tag)
         t = pickle.loads(s)
         self.assert_(isinstance(t, XmpTag))
         self.assertEqual(t.key, tag.key)
         self.assertEqual(t.type, tag.type)
         self.assertEqual(t.name, tag.name)
         self.assertEqual(t.title, tag.title)
         self.assertEqual(t.description, tag.description)
         self.assertEqual(t.raw_value, tag.raw_value)
         self.assertEqual(t.value, tag.value)
Example #35
0
def write_exif(filename, coordinates):
    '''
    Write Lat Lon Direction
    '''

    metadata = pyexiv2.ImageMetadata(filename)
    metadata.read()

    try:

        # convert decimal coordinates into degrees, minutes and seconds as fractions for EXIF
        #exiv_lat = (make_fraction(48,1), make_fraction(58,1), make_fraction(int(52.69876547*1000000),1000000))
        exiv_lat = (make_fraction(int(coordinates[0]),
                                  1), make_fraction(int(coordinates[1]), 1),
                    make_fraction(int(float(coordinates[2]) * 1000000),
                                  1000000))
        exiv_lon = (make_fraction(int(coordinates[4]),
                                  1), make_fraction(int(coordinates[5]), 1),
                    make_fraction(int(float(coordinates[6]) * 1000000),
                                  1000000))

        # convert direction into fraction
        exiv_bearing = make_fraction(int(coordinates[8] * 10), 10)

        # add to exif
        metadata["Exif.GPSInfo.GPSLatitude"] = exiv_lat
        metadata["Exif.GPSInfo.GPSLatitudeRef"] = coordinates[3]
        metadata["Exif.GPSInfo.GPSLongitude"] = exiv_lon
        metadata["Exif.GPSInfo.GPSLongitudeRef"] = coordinates[7]
        metadata["Exif.GPSInfo.GPSMapDatum"] = "WGS-84"
        metadata["Exif.GPSInfo.GPSVersionID"] = '2 0 0 0'
        metadata["Exif.GPSInfo.GPSImgDirection"] = exiv_bearing
        metadata["Exif.GPSInfo.GPSImgDirectionRef"] = "T"
        metadata.write()
        print("Added geodata to: {0}".format(filename))
    except ValueError, e:
        print("Skipping {0}: {1}".format(filename, e))
Example #36
0
    def add_lat_lon(self, lat, lon, precision=1000000):
        ''' Add lat, lon to gps (lat, lon in float)
        @source: originally from geotag_from_gpx.py
        '''

        # convert decimal coordinates into degrees, minutes and seconds
        lat_deg = decimal_to_dms(lat, ["S", "N"])
        lon_deg = decimal_to_dms(lon, ["W", "E"])

        # convert degrees, minutes and seconds as fractions for EXIF
        exiv_lat = (make_fraction(lat_deg[0],1), make_fraction(int(lat_deg[1]),1), make_fraction(int(lat_deg[2]*precision),precision))
        exiv_lon = (make_fraction(lon_deg[0],1), make_fraction(int(lon_deg[1]),1), make_fraction(int(lon_deg[2]*precision),precision))

        # add to exif
        self.metadata["Exif.GPSInfo.GPSLatitude"] = exiv_lat
        self.metadata["Exif.GPSInfo.GPSLatitudeRef"] = lat_deg[3]
        self.metadata["Exif.GPSInfo.GPSLongitude"] = exiv_lon
        self.metadata["Exif.GPSInfo.GPSLongitudeRef"] = lon_deg[3]
        self.metadata["Exif.Image.GPSTag"] = 654
        self.metadata["Exif.GPSInfo.GPSMapDatum"] = "WGS-84"
        self.metadata["Exif.GPSInfo.GPSVersionID"] = '2 0 0 0'
Example #37
0
    def _convert_to_python(self, value, type):
        """
        Convert a raw value to its corresponding python type.

        :param value: the raw value to be converted
        :type value: string
        :param type: the simple type of the raw value
        :type type: string

        :return: the value converted to its corresponding python type

        :raise XmpValueError: if the conversion fails
        """
        if type == 'Boolean':
            if value == 'True':
                return True
            elif value == 'False':
                return False
            else:
                raise XmpValueError(value, type)

        elif type == 'Colorant':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type)

        elif type == 'Date':
            match = self._date_re.match(value)
            if match is None:
                raise XmpValueError(value, type)
            gd = match.groupdict()
            if gd['month'] is not None:
                month = int(gd['month'])
            else:
                month = 1
            if gd['day'] is not None:
                day = int(gd['day'])
            else:
                day = 1
            if gd['time'] is None:
                try:
                    return datetime.date(int(gd['year']), month, day)
                except ValueError:
                    raise XmpValueError(value, type)
            else:
                if gd['minutes'] is None:
                    # Malformed time
                    raise XmpValueError(value, type)
                if gd['seconds'] is not None:
                    seconds = int(gd['seconds'])
                else:
                    seconds = 0
                if gd['decimal'] is not None:
                    microseconds = int(float('0.%s' % gd['decimal']) * 1E6)
                else:
                    microseconds = 0
                if gd['tzd'] == 'Z':
                    tzinfo = FixedOffset()
                else:
                    tzinfo = FixedOffset(gd['sign'], int(gd['ohours']),
                                         int(gd['ominutes']))
                try:
                    return datetime.datetime(int(gd['year']), month, day,
                                             int(gd['hours']), int(gd['minutes']),
                                             seconds, microseconds, tzinfo)
                except ValueError:
                    raise XmpValueError(value, type)

        elif type == 'Dimensions':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type)

        elif type == 'Font':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type)

        elif type == 'GPSCoordinate':
            try:
                return GPSCoordinate.from_string(value)
            except ValueError:
                raise XmpValueError(value, type)

        elif type == 'Integer':
            try:
                return int(value)
            except ValueError:
                raise XmpValueError(value, type)

        elif type == 'Locale':
            # TODO
            # See RFC 3066
            raise NotImplementedError('XMP conversion for type [%s]' % type)

        elif type == 'MIMEType':
            if value.count('/') != 1:
                raise XmpValueError(value, type)
            try:
                return tuple(value.split('/', 1))
            except ValueError:
                raise XmpValueError(value, type)

        elif type == 'Rational':
            try:
                return make_fraction(value)
            except (ValueError, ZeroDivisionError):
                raise XmpValueError(value, type)

        elif type == 'Real':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type)

        elif type in ('AgentName', 'ProperName', 'Text'):
            try:
                return unicode(value, 'utf-8')
            except TypeError:
                raise XmpValueError(value, type)

        elif type == 'Thumbnail':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type)

        elif type in ('URI', 'URL'):
            return value

        elif type == 'XPath':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type)

        raise NotImplementedError('XMP conversion for type [%s]' % type)
Example #38
0
 def test_fraction_to_string(self):
     self.assertEqual(fraction_to_string(make_fraction(3, 5)), '3/5')
     self.assertEqual(fraction_to_string(make_fraction(-3, 5)), '-3/5')
     self.assertEqual(fraction_to_string(make_fraction(0, 1)), '0/1')
     self.assertRaises(TypeError, fraction_to_string, None)
     self.assertRaises(TypeError, fraction_to_string, 'invalid')
Example #39
0
    def _convert_to_python(self, value, type_):
        """Convert a raw value to its corresponding python type.

        Args:
        value -- the raw value to be converted
        type_ -- the simple type of the raw value

        Return: the value converted to its corresponding python type

        Raise XmpValueError: if the conversion fails
        """
        if type_ == 'Boolean':
            if value == 'True':
                return True

            elif value == 'False':
                return False

            else:
                raise XmpValueError(value, type_)

        elif type_ == 'Colorant':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type_)

        elif type_ == 'Date':
            match = self._date_re.match(value)
            if match is None:
                raise XmpValueError(value, type_)

            gd = match.groupdict()
            if gd['month'] is not None:
                month = int(gd['month'])

            else:
                month = 1

            if gd['day'] is not None:
                day = int(gd['day'])

            else:
                day = 1

            if gd['time'] is None:
                try:
                    return datetime.date(int(gd['year']), month, day)
                except ValueError:
                    raise XmpValueError(value, type_)

            else:
                if gd['minutes'] is None:
                    # Malformed time
                    raise XmpValueError(value, type_)

                if gd['seconds'] is not None:
                    seconds = int(gd['seconds'])

                else:
                    seconds = 0

                if gd['decimal'] is not None:
                    microseconds = int(float('0.%s' % gd['decimal']) * 1E6)

                else:
                    microseconds = 0

                if gd['tzd'] is not None and gd[
                        'tzd'] == 'Z' and gd['sign'] is None and gd[
                            'ohours'] is None and gd['ominutes'] is None:
                    tzinfo = FixedOffset()

                elif gd['sign'] is not None and gd[
                        'ohours'] is not None and gd['ominutes'] is not None:
                    tzinfo = FixedOffset(gd['sign'], int(gd['ohours']),
                                         int(gd['ominutes']))
                else:
                    tzinfo = None
                    # TODO: Decide if following is way to hande
                    # ======================================================================
                    # ERROR: test_convert_to_python_date (xmp.TestXmpTag)
                    # ----------------------------------------------------------------------
                    # Traceback (most recent call last):
                    #   File "c:\Users\BSFau\Cloudstation\BSFsoftDev\axternal\py3exiv2\py3exiv2\test\xmp.py", line 91, in test_convert_to_python_date
                    #     datetime.datetime(1999, 10, 13, 5, 3, tzinfo=FixedOffset()),
                    # TypeError: can't subtract offset-naive and offset-aware datetimes
                    # ----------------------------------------------------------------------

                    # u_tm = datetime.datetime.utcfromtimestamp(0)
                    # l_tm = datetime.datetime.fromtimestamp(0)
                    # tzinfo = datetime.timezone(l_tm - u_tm)
                try:
                    if tzinfo is not None:
                        return datetime.datetime(int(gd['year']), month, day,
                                                 int(gd['hours']),
                                                 int(gd['minutes']), seconds,
                                                 microseconds, tzinfo)
                    else:
                        return datetime.datetime(int(gd['year']), month, day,
                                                 int(gd['hours']),
                                                 int(gd['minutes']), seconds,
                                                 microseconds)

                except ValueError:
                    raise XmpValueError(value, type_)

        elif type_ == 'Dimensions':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type_)

        elif type_ == 'Font':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type_)

        elif type_ == 'GPSCoordinate':
            try:
                return GPSCoordinate.from_string(value)
            except ValueError:
                raise XmpValueError(value, type_)

        elif type_ == 'Integer':
            try:
                return int(value)
            except ValueError:
                raise XmpValueError(value, type_)

        elif type_ == 'Locale':
            # TODO
            # See RFC 3066
            raise NotImplementedError('XMP conversion for type [%s]' % type_)

        elif type_ == 'MIMEType':
            if value.count('/') != 1:
                raise XmpValueError(value, type_)
            try:
                return tuple(value.split('/', 1))
            except ValueError:
                raise XmpValueError(value, type_)

        elif type_ == 'Rational':
            try:
                return make_fraction(value)
            except (ValueError, ZeroDivisionError):
                raise XmpValueError(value, type_)

        elif type_ == 'Real':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type_)

        elif type_ in ('AgentName', 'ProperName', 'Text'):
            if isinstance(value, bytes):
                try:
                    value = str(value, 'utf-8')
                except TypeError:
                    raise XmpValueError(value, type_)
            return value

        elif type_ == 'Thumbnail':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type_)

        elif type_ in ('URI', 'URL'):
            if isinstance(value, bytes):
                try:
                    value = value.decode('utf-8')
                except UnicodeDecodeError:
                    # Unknow encoding, return the raw value
                    pass
            return value

        elif type_ == 'XPath':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type_)

        raise NotImplementedError('XMP conversion for type [%s]' % type_)
Example #40
0
 def make_fraction(self, v, precision=1000):
     ''' Make fraction with the specified precision
     '''
     fv = make_fraction(int(v * precision), precision)
     return fv
Example #41
0
    def _convert_to_python(self, value):
        """
        Convert one raw value to its corresponding python type.

        :param value: the raw value to be converted
        :type value: string

        :return: the value converted to its corresponding python type

        :raise ExifValueError: if the conversion fails
        """
        if self.type == 'Ascii':
            # The value may contain a Datetime
            for format in self._datetime_formats:
                try:
                    t = time.strptime(value, format)
                except ValueError:
                    continue
                else:
                    return datetime.datetime(*t[:6])
            # Or a Date (e.g. Exif.GPSInfo.GPSDateStamp)
            for format in self._date_formats:
                try:
                    t = time.strptime(value, format)
                except ValueError:
                    continue
                else:
                    return datetime.date(*t[:3])
            # Default to string.
            # There is currently no charset conversion.
            # TODO: guess the encoding and decode accordingly into unicode
            # where relevant.
            return value

        elif self.type in ('Byte', 'SByte'):
            if isinstance(value, bytes):
                return value.decode('utf-8')
            return value

        elif self.type == 'Comment':
            if isinstance(value, str):
                if value.startswith('charset='):
                    charset, val = value.split(' ', 1)
                    return val
                return value

            if value.startswith(b'charset='):
                charset = charset.split('=')[1].strip('"')
                encoding = self._match_encoding(charset)
                return val.decode(encoding, 'replace')

            else:
                # No encoding defined.
                try:
                    return value.decode('utf-8')
                except UnicodeError:
                    pass

            return value

        elif self.type in ('Short', 'SShort'):
            try:
                return int(value)
            except ValueError:
                raise ExifValueError(value, self.type)

        elif self.type in ('Long', 'SLong'):
            try:
                return int(value)
            except ValueError:
                raise ExifValueError(value, self.type)

        elif self.type in ('Rational', 'SRational'):
            try:
                r = make_fraction(value)
            except (ValueError, ZeroDivisionError):
                raise ExifValueError(value, self.type)

            else:
                if self.type == 'Rational' and r.numerator < 0:
                    raise ExifValueError(value, self.type)
                return r

        elif self.type == 'Undefined':
            # There is currently no charset conversion.
            # TODO: guess the encoding and decode accordingly into unicode
            # where relevant.
            return undefined_to_string(value)

        raise ExifValueError(value, self.type)
Example #42
0
def test_make_fraction_valid(args, frac):
    assert make_fraction(*args) == Fraction(*frac)
Example #43
0
def test_make_fraction_invalid(exc, args):
    with pytest.raises(exc):
        make_fraction(*args)
Example #44
0
    def testReadMetadataXMP(self):
        filename = os.path.join('data', 'exiv2-bug540.jpg')
        filepath = testutils.get_absolute_file_path(filename)
        md5sum = '64d4b7eab1e78f1f6bfb3c966e99eef2'
        self.assertCorrectFile(filepath, md5sum)

        # Read the image metadata
        image = pyexiv2.ImageMetadata(filepath)
        image.read()

        xmpTags = [('Xmp.dc.creator', list, [u'Ian Britton']),
                   ('Xmp.dc.description', dict, {u'x-default': u'Communications'}),
                   ('Xmp.dc.rights', dict, {u'x-default': u'ian Britton - FreeFoto.com'}),
                   ('Xmp.dc.source', unicode, u'FreeFoto.com'),
                   ('Xmp.dc.subject', list, [u'Communications']),
                   ('Xmp.dc.title', dict, {u'x-default': u'Communications'}),
                   ('Xmp.exif.ApertureValue', FRACTION, make_fraction(8, 1)),
                   ('Xmp.exif.BrightnessValue', FRACTION, make_fraction(333, 1280)),
                   ('Xmp.exif.ColorSpace', int, 1),
                   ('Xmp.exif.DateTimeOriginal',
                    datetime.datetime,
                    datetime.datetime(2002, 7, 13, 15, 58, 28, tzinfo=pyexiv2.utils.FixedOffset())),
                   ('Xmp.exif.ExifVersion', unicode, u'0200'),
                   ('Xmp.exif.ExposureBiasValue', FRACTION, make_fraction(-13, 20)),
                   ('Xmp.exif.ExposureProgram', int, 4),
                   ('Xmp.exif.FNumber', FRACTION, make_fraction(3, 5)),
                   ('Xmp.exif.FileSource', int, 0),
                   ('Xmp.exif.FlashpixVersion', unicode, u'0100'),
                   ('Xmp.exif.FocalLength', FRACTION, make_fraction(0, 1)),
                   ('Xmp.exif.FocalPlaneResolutionUnit', int, 2),
                   ('Xmp.exif.FocalPlaneXResolution', FRACTION, make_fraction(3085, 256)),
                   ('Xmp.exif.FocalPlaneYResolution', FRACTION, make_fraction(3085, 256)),
                   ('Xmp.exif.GPSLatitude',
                    pyexiv2.utils.GPSCoordinate,
                    pyexiv2.utils.GPSCoordinate.from_string('54,59.380000N')),
                   ('Xmp.exif.GPSLongitude',
                    pyexiv2.utils.GPSCoordinate,
                    pyexiv2.utils.GPSCoordinate.from_string('1,54.850000W')),
                   ('Xmp.exif.GPSMapDatum', unicode, u'WGS84'),
                   ('Xmp.exif.GPSTimeStamp',
                    datetime.datetime,
                    datetime.datetime(2002, 7, 13, 14, 58, 24, tzinfo=pyexiv2.utils.FixedOffset())),
                   ('Xmp.exif.GPSVersionID', unicode, u'2.0.0.0'),
                   ('Xmp.exif.ISOSpeedRatings', list, [0]),
                   ('Xmp.exif.MeteringMode', int, 5),
                   ('Xmp.exif.PixelXDimension', int, 2400),
                   ('Xmp.exif.PixelYDimension', int, 1600),
                   ('Xmp.exif.SceneType', int, 0),
                   ('Xmp.exif.SensingMethod', int, 2),
                   ('Xmp.exif.ShutterSpeedValue', FRACTION, make_fraction(30827, 3245)),
                   ('Xmp.pdf.Keywords', unicode, u'Communications'),
                   ('Xmp.photoshop.AuthorsPosition', unicode, u'Photographer'),
                   ('Xmp.photoshop.CaptionWriter', unicode, u'Ian Britton'),
                   ('Xmp.photoshop.Category', unicode, u'BUS'),
                   ('Xmp.photoshop.City', unicode, u' '),
                   ('Xmp.photoshop.Country', unicode, u'Ubited Kingdom'),
                   ('Xmp.photoshop.Credit', unicode, u'Ian Britton'),
                   ('Xmp.photoshop.DateCreated', datetime.date, datetime.date(2002, 6, 20)),
                   ('Xmp.photoshop.Headline', unicode, u'Communications'),
                   ('Xmp.photoshop.State', unicode, u' '),
                   ('Xmp.photoshop.SupplementalCategories', list, [u'Communications']),
                   ('Xmp.photoshop.Urgency', int, 5),
                   ('Xmp.tiff.Artist', unicode, u'Ian Britton'),
                   ('Xmp.tiff.BitsPerSample', list, [8]),
                   ('Xmp.tiff.Compression', int, 6),
                   ('Xmp.tiff.Copyright',
                    dict,
                    {u'x-default': u'ian Britton - FreeFoto.com'}),
                   ('Xmp.tiff.ImageDescription', dict, {u'x-default': u'Communications'}),
                   ('Xmp.tiff.ImageLength', int, 400),
                   ('Xmp.tiff.ImageWidth', int, 600),
                   ('Xmp.tiff.Make', unicode, u'FUJIFILM'),
                   ('Xmp.tiff.Model', unicode, u'FinePixS1Pro'),
                   ('Xmp.tiff.Orientation', int, 1),
                   ('Xmp.tiff.ResolutionUnit', int, 2),
                   ('Xmp.tiff.Software', unicode, u'Adobe Photoshop 7.0'),
                   ('Xmp.tiff.XResolution', FRACTION, make_fraction(300, 1)),
                   ('Xmp.tiff.YCbCrPositioning', int, 2),
                   ('Xmp.tiff.YResolution', FRACTION, make_fraction(300, 1)),
                   ('Xmp.xmp.CreateDate',
                    datetime.datetime,
                    datetime.datetime(2002, 7, 13, 15, 58, 28, tzinfo=pyexiv2.utils.FixedOffset())),
                   ('Xmp.xmp.ModifyDate',
                    datetime.datetime,
                    datetime.datetime(2002, 7, 19, 13, 28, 10, tzinfo=pyexiv2.utils.FixedOffset())),
                   ('Xmp.xmpBJ.JobRef', list, []),
                   ('Xmp.xmpBJ.JobRef[1]', str, ''),
                   ('Xmp.xmpBJ.JobRef[1]/stJob:name', str, 'Photographer'),
                   ('Xmp.xmpMM.DocumentID',
                    str,
                    'adobe:docid:photoshop:84d4dba8-9b11-11d6-895d-c4d063a70fb0'),
                   ('Xmp.xmpRights.Marked', bool, True),
                   ('Xmp.xmpRights.WebStatement', str, 'www.freefoto.com')]
        self.assertEqual(image.xmp_keys, [tag[0] for tag in xmpTags])
        for key, ktype, value in xmpTags:
            self.check_type_and_value(image[key], ktype, value)
Example #45
0
 def make_fraction(self, v, precision=1000):
     ''' Make fraction with the specified precision
     '''
     fv = make_fraction(int(v * precision), precision)
     return fv
Example #46
0
File: exif.py Project: Namejs/workr
    def _convert_to_python(self, value):
        """
        Convert one raw value to its corresponding python type.

        :param value: the raw value to be converted
        :type value: string

        :return: the value converted to its corresponding python type

        :raise ExifValueError: if the conversion fails
        """
        if self.type == 'Ascii':
            # The value may contain a Datetime
            for format in self._datetime_formats:
                try:
                    t = time.strptime(value, format)
                except ValueError:
                    continue
                else:
                    return datetime.datetime(*t[:6])
            # Or a Date (e.g. Exif.GPSInfo.GPSDateStamp)
            for format in self._date_formats:
                try:
                    t = time.strptime(value, format)
                except ValueError:
                    continue
                else:
                    return datetime.date(*t[:3])
            # Default to string.
            # There is currently no charset conversion.
            # TODO: guess the encoding and decode accordingly into unicode
            # where relevant.
            return value

        elif self.type in ('Byte', 'SByte'):
            return value

        elif self.type == 'Comment':
            if value.startswith('charset='):
                charset, val = value.split(' ', 1)
                charset = charset.split('=')[1].strip('"')
                encoding = self._match_encoding(charset)
                return val.decode(encoding, 'replace')
            else:
                # No encoding defined.
                try:
                    return value.decode('utf-8')
                except UnicodeError:
                    return value

        elif self.type in ('Short', 'SShort'):
            try:
                return int(value)
            except ValueError:
                raise ExifValueError(value, self.type)

        elif self.type in ('Long', 'SLong'):
            try:
                return long(value)
            except ValueError:
                raise ExifValueError(value, self.type)

        elif self.type in ('Rational', 'SRational'):
            try:
                r = make_fraction(value)
            except (ValueError, ZeroDivisionError):
                raise ExifValueError(value, self.type)
            else:
                if self.type == 'Rational' and r.numerator < 0:
                    raise ExifValueError(value, self.type)
                return r

        elif self.type == 'Undefined':
            # There is currently no charset conversion.
            # TODO: guess the encoding and decode accordingly into unicode
            # where relevant.
            return undefined_to_string(value)

        raise ExifValueError(value, self.type)
Example #47
0
    def _convert_to_python(self, value, type_):
        """Convert a raw value to its corresponding python type.

        Args:
        value -- the raw value to be converted
        type_ -- the simple type of the raw value

        Return: the value converted to its corresponding python type

        Raise XmpValueError: if the conversion fails
        """
        if type_ == 'Boolean':
            if value == 'True':
                return True

            elif value == 'False':
                return False

            else:
                raise XmpValueError(value, type_)

        elif type_ == 'Colorant':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type_)

        elif type_ == 'Date':
            match = self._date_re.match(value)
            if match is None:
                raise XmpValueError(value, type_)

            gd = match.groupdict()
            if gd['month'] is not None:
                month = int(gd['month'])

            else:
                month = 1

            if gd['day'] is not None:
                day = int(gd['day'])

            else:
                day = 1

            if gd['time'] is None:
                try:
                    return datetime.date(int(gd['year']), month, day)
                except ValueError:
                    raise XmpValueError(value, type_)

            else:
                if gd['minutes'] is None:
                    # Malformed time
                    raise XmpValueError(value, type_)

                if gd['seconds'] is not None:
                    seconds = int(gd['seconds'])

                else:
                    seconds = 0

                if gd['decimal'] is not None:
                    microseconds = int(float('0.%s' % gd['decimal']) * 1E6)

                else:
                    microseconds = 0

                if gd['tzd'] == 'Z':
                    tzinfo = FixedOffset()

                else:
                    tzinfo = FixedOffset(gd['sign'], int(gd['ohours']),
                                         int(gd['ominutes']))

                try:
                    return datetime.datetime(int(gd['year']), month, day,
                                             int(gd['hours']),
                                             int(gd['minutes']), seconds,
                                             microseconds, tzinfo)
                except ValueError:
                    raise XmpValueError(value, type_)

        elif type_ == 'Dimensions':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type_)

        elif type_ == 'Font':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type_)

        elif type_ == 'GPSCoordinate':
            try:
                return GPSCoordinate.from_string(value)
            except ValueError:
                raise XmpValueError(value, type_)

        elif type_ == 'Integer':
            try:
                return int(value)
            except ValueError:
                raise XmpValueError(value, type_)

        elif type_ == 'Locale':
            # TODO
            # See RFC 3066
            raise NotImplementedError('XMP conversion for type [%s]' % type_)

        elif type_ == 'MIMEType':
            if value.count('/') != 1:
                raise XmpValueError(value, type_)
            try:
                return tuple(value.split('/', 1))
            except ValueError:
                raise XmpValueError(value, type_)

        elif type_ == 'Rational':
            try:
                return make_fraction(value)
            except (ValueError, ZeroDivisionError):
                raise XmpValueError(value, type_)

        elif type_ == 'Real':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type_)

        elif type_ in ('AgentName', 'ProperName', 'Text'):
            if isinstance(value, bytes):
                try:
                    value = str(value, 'utf-8')
                except TypeError:
                    raise XmpValueError(value, type_)
            return value

        elif type_ == 'Thumbnail':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type_)

        elif type_ in ('URI', 'URL'):
            if isinstance(value, bytes):
                try:
                    value = value.decode('utf-8')
                except UnicodeDecodeError:
                    # Unknow encoding, return the raw value
                    pass
            return value

        elif type_ == 'XPath':
            # TODO
            raise NotImplementedError('XMP conversion for type [%s]' % type_)

        raise NotImplementedError('XMP conversion for type [%s]' % type_)
Example #48
0
 def test_fraction_to_string(self):
     self.assertEqual(fraction_to_string(make_fraction(3, 5)), '3/5')
     self.assertEqual(fraction_to_string(make_fraction(-3, 5)), '-3/5')
     self.assertEqual(fraction_to_string(make_fraction(0, 1)), '0/1')
     self.assertRaises(TypeError, fraction_to_string, None)
     self.assertRaises(TypeError, fraction_to_string, 'invalid')
Example #49
0
def downloadPhoto(path, photoId, photoNum=None):
    """Downloads an image and sets exif data.

    Keyword arguments:
    path -- a string containing the name of the directory to write to
    photoId -- a string containing the ID number of the image to download
    """

    # create the directory to store the images
    setPath = path.replace("/", "-")
    if not os.path.exists(setPath):
        os.makedirs(setPath)

    # download the photo metadata
    photoInfo = flickr.photos.getInfo(photo_id=photoId).find('photo')

    # work out a filename for the photo once downloaded
    filename = path + os.sep + generateFilename(photoInfo, photoNum)

    # try downloading the file
    try:
        sizes = flickr.photos.getSizes(photo_id=photoId).find('sizes')
        if filename.endswith('.mp4'):
            url = sizes.find('.//size[@label="Video Original"]').get('source')
        else:
            url = sizes.find('.//size[@label="Original"]').get('source')
        urllib.request.urlretrieve(url, filename)
        print(filename)
    except:
        return

    # a place to build up the exif info to write
    photoExif = {}

    if not filename.endswith('.mp4'):
        # work out the exif and XMP vales
        photoExif['Exif.Image.Copyright'] = getCopyright(photoInfo)
        photoExif['Exif.Image.Artist'] = getOwner(photoInfo)
        photoExif['Xmp.dc.rights'] = photoExif['Exif.Image.Copyright']
        photoExif['Xmp.dc.creator'] = [getOwner(photoInfo)]
        photoExif['Xmp.xmpRights.Owner'] = photoExif['Xmp.dc.creator']
        photoExif['Xmp.xmpRights.Marked'] = True
        photoExif['Xmp.xmpRights.UsageTerms'] = getLicense(photoInfo)
        photoExif['Xmp.dc.title'] = photoInfo.find('title').text or 'Unknown'
        photoExif['Exif.Image.ImageDescription'] = photoExif['Xmp.dc.title']

        # only set the description if there's one to set (or default to setting the same as the title)
        description = photoInfo.find('description').text
        if description is None:
            description = photoExif['Xmp.dc.title']
        photoExif['Xmp.dc.description'] = description
        photoExif['Exif.Photo.UserComment'] = description

        # set the subject using the image tags (if there are any)
        tags = []
        for tag in photoInfo.find('tags').getiterator('tag'):
            tags.append(tag.text)
        if len(tags) > 0:
            photoExif['Xmp.dc.subject'] = tags

        # set the date taken
        taken = photoInfo.find('dates').get('taken')
        takenFormatted = datetime.datetime.strptime(taken, '%Y-%m-%d %H:%M:%S')
        photoExif['Xmp.dc.date'] = [takenFormatted]
        photoExif['Xmp.xmp.CreateDate'] = takenFormatted

        # add GPS coordinates if available
        location = photoInfo.find('location')
        if location is not None:
            lat = gpsDecimalLatToDMS(float(location.get('latitude')))
            lon = gpsDecimalLonToDMS(float(location.get('longitude')))
            latDMS = (make_fraction(lat[0], 1), make_fraction(int(lat[1]), 1),
                      make_fraction(int(lat[2] * 1000000), 1000000))
            lonDMS = (make_fraction(lon[0], 1), make_fraction(int(lon[1]), 1),
                      make_fraction(int(lon[2] * 1000000), 1000000))
            photoExif["Exif.GPSInfo.GPSVersionID"] = '2 0 0 0'
            photoExif["Exif.GPSInfo.GPSLatitude"] = latDMS
            photoExif["Exif.GPSInfo.GPSLatitudeRef"] = lat[3]
            photoExif["Exif.GPSInfo.GPSLongitude"] = lonDMS
            photoExif["Exif.GPSInfo.GPSLongitudeRef"] = lon[3]
            photoExif[
                "Exif.GPSInfo.GPSDateStamp"] = datetime.datetime.strptime(
                    taken, '%Y-%m-%d %H:%M:%S').strftime('%Y:%m:%d')

        setExif(filename, photoExif)
Example #50
0
    def testReadMetadataXMP(self):
        filename = os.path.join('data', 'exiv2-bug540.jpg')
        filepath = testutils.get_absolute_file_path(filename)
        md5sum = '64d4b7eab1e78f1f6bfb3c966e99eef2'
        self.assertCorrectFile(filepath, md5sum)

        # Read the image metadata
        image = pyexiv2.ImageMetadata(filepath)
        image.read()

        xmpTags = [
            ('Xmp.dc.creator', list, [u'Ian Britton']),
            ('Xmp.dc.description', dict, {
                u'x-default': u'Communications'
            }),
            ('Xmp.dc.rights', dict, {
                u'x-default': u'ian Britton - FreeFoto.com'
            }), ('Xmp.dc.source', unicode, u'FreeFoto.com'),
            ('Xmp.dc.subject', list, [u'Communications']),
            ('Xmp.dc.title', dict, {
                u'x-default': u'Communications'
            }), ('Xmp.exif.ApertureValue', FRACTION, make_fraction(8, 1)),
            ('Xmp.exif.BrightnessValue', FRACTION, make_fraction(333, 1280)),
            ('Xmp.exif.ColorSpace', int, 1),
            ('Xmp.exif.DateTimeOriginal', datetime.datetime,
             datetime.datetime(2002,
                               7,
                               13,
                               15,
                               58,
                               28,
                               tzinfo=pyexiv2.utils.FixedOffset())),
            ('Xmp.exif.ExifVersion', unicode, u'0200'),
            ('Xmp.exif.ExposureBiasValue', FRACTION, make_fraction(-13, 20)),
            ('Xmp.exif.ExposureProgram', int, 4),
            ('Xmp.exif.FNumber', FRACTION, make_fraction(3, 5)),
            ('Xmp.exif.FileSource', int, 0),
            ('Xmp.exif.FlashpixVersion', unicode, u'0100'),
            ('Xmp.exif.FocalLength', FRACTION, make_fraction(0, 1)),
            ('Xmp.exif.FocalPlaneResolutionUnit', int, 2),
            ('Xmp.exif.FocalPlaneXResolution', FRACTION,
             make_fraction(3085, 256)),
            ('Xmp.exif.FocalPlaneYResolution', FRACTION,
             make_fraction(3085, 256)),
            ('Xmp.exif.GPSLatitude', pyexiv2.utils.GPSCoordinate,
             pyexiv2.utils.GPSCoordinate.from_string('54,59.380000N')),
            ('Xmp.exif.GPSLongitude', pyexiv2.utils.GPSCoordinate,
             pyexiv2.utils.GPSCoordinate.from_string('1,54.850000W')),
            ('Xmp.exif.GPSMapDatum', unicode, u'WGS84'),
            ('Xmp.exif.GPSTimeStamp', datetime.datetime,
             datetime.datetime(2002,
                               7,
                               13,
                               14,
                               58,
                               24,
                               tzinfo=pyexiv2.utils.FixedOffset())),
            ('Xmp.exif.GPSVersionID', unicode, u'2.0.0.0'),
            ('Xmp.exif.ISOSpeedRatings', list, [0]),
            ('Xmp.exif.MeteringMode', int, 5),
            ('Xmp.exif.PixelXDimension', int, 2400),
            ('Xmp.exif.PixelYDimension', int, 1600),
            ('Xmp.exif.SceneType', int, 0), ('Xmp.exif.SensingMethod', int, 2),
            ('Xmp.exif.ShutterSpeedValue', FRACTION,
             make_fraction(30827, 3245)),
            ('Xmp.pdf.Keywords', unicode, u'Communications'),
            ('Xmp.photoshop.AuthorsPosition', unicode, u'Photographer'),
            ('Xmp.photoshop.CaptionWriter', unicode, u'Ian Britton'),
            ('Xmp.photoshop.Category', unicode, u'BUS'),
            ('Xmp.photoshop.City', unicode, u' '),
            ('Xmp.photoshop.Country', unicode, u'Ubited Kingdom'),
            ('Xmp.photoshop.Credit', unicode, u'Ian Britton'),
            ('Xmp.photoshop.DateCreated', datetime.date,
             datetime.date(2002, 6, 20)),
            ('Xmp.photoshop.Headline', unicode, u'Communications'),
            ('Xmp.photoshop.State', unicode, u' '),
            ('Xmp.photoshop.SupplementalCategories', list, [u'Communications'
                                                            ]),
            ('Xmp.photoshop.Urgency', int, 5),
            ('Xmp.tiff.Artist', unicode, u'Ian Britton'),
            ('Xmp.tiff.BitsPerSample', list, [8]),
            ('Xmp.tiff.Compression', int, 6),
            ('Xmp.tiff.Copyright', dict, {
                u'x-default': u'ian Britton - FreeFoto.com'
            }),
            ('Xmp.tiff.ImageDescription', dict, {
                u'x-default': u'Communications'
            }), ('Xmp.tiff.ImageLength', int, 400),
            ('Xmp.tiff.ImageWidth', int, 600),
            ('Xmp.tiff.Make', unicode, u'FUJIFILM'),
            ('Xmp.tiff.Model', unicode, u'FinePixS1Pro'),
            ('Xmp.tiff.Orientation', int, 1),
            ('Xmp.tiff.ResolutionUnit', int, 2),
            ('Xmp.tiff.Software', unicode, u'Adobe Photoshop 7.0'),
            ('Xmp.tiff.XResolution', FRACTION, make_fraction(300, 1)),
            ('Xmp.tiff.YCbCrPositioning', int, 2),
            ('Xmp.tiff.YResolution', FRACTION, make_fraction(300, 1)),
            ('Xmp.xmp.CreateDate', datetime.datetime,
             datetime.datetime(2002,
                               7,
                               13,
                               15,
                               58,
                               28,
                               tzinfo=pyexiv2.utils.FixedOffset())),
            ('Xmp.xmp.ModifyDate', datetime.datetime,
             datetime.datetime(2002,
                               7,
                               19,
                               13,
                               28,
                               10,
                               tzinfo=pyexiv2.utils.FixedOffset())),
            ('Xmp.xmpBJ.JobRef', list, []), ('Xmp.xmpBJ.JobRef[1]', str, ''),
            ('Xmp.xmpBJ.JobRef[1]/stJob:name', str, 'Photographer'),
            ('Xmp.xmpMM.DocumentID', str,
             'adobe:docid:photoshop:84d4dba8-9b11-11d6-895d-c4d063a70fb0'),
            ('Xmp.xmpRights.Marked', bool, True),
            ('Xmp.xmpRights.WebStatement', str, 'www.freefoto.com')
        ]
        self.assertEqual(image.xmp_keys, [tag[0] for tag in xmpTags])
        for key, ktype, value in xmpTags:
            self.check_type_and_value(image[key], ktype, value)