예제 #1
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 = ExifEdit(filename)

    # 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)
        corrected_bearing = (bearing + offset_bearing) % 360
        metadata.add_lat_lon(lat, lon)
        metadata.add_direction(corrected_bearing)
        if elevation is not None:
            metadata.add_altitude(elevation)
        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))
예제 #2
0
    def test_load_and_dump_corrupt_exif_2(self):

        corrupt_exifedit = ExifEdit(CORRUPT_EXIF_FILE_2)

        error_raised = False
        try:
            corrupt_exifedit.write(FIXED_EXIF_FILE_2)
        except:
            error_raised = True
        self.assertFalse(error_raised, 'EXIF load and dump back failed')
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
    '''
    exif = ExifEdit(filename)
    try:
        exif.add_direction(direction, precision=10)
        exif.write()
        print("Added direction to: {0} ({1} degrees)".format(filename, float(direction)))
    except ValueError, e:
        print("Skipping {0}: {1}".format(filename, e))
예제 #4
0
def write_exif(filename, coordinates):
    '''
    Write Lat Lon Direction
    '''

    metadata = metadata = ExifEdit(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.add_lat_lon(coordinates.lat.decimal_degree,
                             coordinates.lon.decimal_degree)

        metadata.write()
        print("Added geodata to: {0}".format(filename))
    except ValueError, e:
        print("Skipping {0}: {1}".format(filename, e))
예제 #5
0
def create_mapillary_description(
    filename, username, email, upload_hash, sequence_uuid, interpolated_heading=0.0, verbose=False
):
    """
    Check that image file has the required EXIF fields.

    Incompatible files will be ignored server side.
    """
    # read exif
    exif = EXIF(filename)

    if not verify_exif(filename):
        return False

    # write the mapillary tag
    mapillary_description = {}
    mapillary_description["MAPLongitude"], mapillary_description["MAPLatitude"] = exif.extract_lon_lat()
    # required date format: 2015_01_14_09_37_01_000
    mapillary_description["MAPCaptureTime"] = datetime.datetime.strftime(
        exif.extract_capture_time(), "%Y_%m_%d_%H_%M_%S_%f"
    )[:-3]
    mapillary_description["MAPOrientation"] = exif.extract_orientation()
    heading = exif.extract_direction()
    heading = normalize_bearing(interpolated_heading) if heading is None else normalize_bearing(heading)
    mapillary_description["MAPCompassHeading"] = {"TrueHeading": heading, "MagneticHeading": heading}
    mapillary_description["MAPSettingsUploadHash"] = upload_hash
    mapillary_description["MAPSettingsEmail"] = email
    mapillary_description["MAPSettingsUsername"] = username
    settings_upload_hash = hashlib.sha256("%s%s%s" % (upload_hash, email, base64.b64encode(filename))).hexdigest()
    mapillary_description["MAPSettingsUploadHash"] = settings_upload_hash
    mapillary_description["MAPPhotoUUID"] = str(uuid.uuid4())
    mapillary_description["MAPSequenceUUID"] = str(sequence_uuid)
    mapillary_description["MAPDeviceModel"] = exif.extract_model()
    mapillary_description["MAPDeviceMake"] = exif.extract_make()

    # write to file
    json_desc = json.dumps(mapillary_description)
    if verbose:
        print "tag: {0}".format(json_desc)
    metadata = ExifEdit(filename)
    metadata.add_image_description(json_desc)
    metadata.write()
예제 #6
0
def add_orientation_general(test_obj, filename):

    test_orientation = 2

    empty_exifedit = ExifEdit(filename)

    empty_exifedit.add_orientation(test_orientation)
    empty_exifedit.write(EMPTY_EXIF_FILE_TEST)

    exif_data = load_exif()
    test_obj.assertEqual(test_orientation,
                         exif_data[EXIF_PRIMARY_TAGS_DICT['Orientation']])
예제 #7
0
def create_mapillary_description(filename,
                                 username,
                                 email,
                                 upload_hash,
                                 sequence_uuid,
                                 interpolated_heading=0.0,
                                 verbose=False):
    '''
    Check that image file has the required EXIF fields.

    Incompatible files will be ignored server side.
    '''
    # read exif
    exif = EXIF(filename)

    if not verify_exif(filename):
        return False

    # write the mapillary tag
    mapillary_description = {}
    mapillary_description["MAPLongitude"], mapillary_description[
        "MAPLatitude"] = exif.extract_lon_lat()
    #required date format: 2015_01_14_09_37_01_000
    mapillary_description["MAPCaptureTime"] = datetime.datetime.strftime(
        exif.extract_capture_time(), "%Y_%m_%d_%H_%M_%S_%f")[:-3]
    mapillary_description["MAPOrientation"] = exif.extract_orientation()
    heading = exif.extract_direction()
    heading = normalize_bearing(
        interpolated_heading) if heading is None else normalize_bearing(
            heading)
    mapillary_description["MAPCompassHeading"] = {
        "TrueHeading": heading,
        "MagneticHeading": heading
    }
    mapillary_description["MAPSettingsUploadHash"] = upload_hash
    mapillary_description["MAPSettingsEmail"] = email
    mapillary_description["MAPSettingsUsername"] = username
    settings_upload_hash = hashlib.sha256(
        "%s%s%s" %
        (upload_hash, email, base64.b64encode(filename))).hexdigest()
    mapillary_description['MAPSettingsUploadHash'] = settings_upload_hash
    mapillary_description['MAPPhotoUUID'] = str(uuid.uuid4())
    mapillary_description['MAPSequenceUUID'] = str(sequence_uuid)
    mapillary_description['MAPDeviceModel'] = exif.extract_model()
    mapillary_description['MAPDeviceMake'] = exif.extract_make()

    # write to file
    json_desc = json.dumps(mapillary_description)
    if verbose:
        print "tag: {0}".format(json_desc)
    metadata = ExifEdit(filename)
    metadata.add_image_description(json_desc)
    metadata.write()
예제 #8
0
def add_date_time_original_general(test_obj, filename):

    test_datetime = datetime.datetime(2016, 8, 31, 8, 29, 26, 249000)

    empty_exifedit = ExifEdit(filename)

    empty_exifedit.add_date_time_original(test_datetime)
    empty_exifedit.write(EMPTY_EXIF_FILE_TEST)

    exif_data = load_exif()
    test_obj.assertEqual(
        test_datetime.strftime('%Y:%m:%d %H:%M:%S.%f')[:-3],
        exif_data[EXIF_PRIMARY_TAGS_DICT['DateTimeOriginal']])
예제 #9
0
    def test_write_to_non_existing_file(self):

        test_datetime = datetime.datetime(2016, 8, 31, 8, 29, 26, 249000)

        empty_exifedit = ExifEdit(EMPTY_EXIF_FILE_TEST)

        empty_exifedit.add_date_time_original(test_datetime)
        empty_exifedit.write(NON_EXISTING_FILE)

        exif_data = load_exif(NON_EXISTING_FILE)
        self.assertEqual(
            test_datetime.strftime('%Y:%m:%d %H:%M:%S.%f')[:-3],
            exif_data[EXIF_PRIMARY_TAGS_DICT['DateTimeOriginal']])
예제 #10
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
    '''
    exif = ExifEdit(filename)
    try:
        exif.add_direction(direction, precision=10)
        exif.write()
        print("Added direction to: {0} ({1} degrees)".format(
            filename, float(direction)))
    except ValueError, e:
        print("Skipping {0}: {1}".format(filename, e))
예제 #11
0
def add_camera_make_model_general(test_obj, filename):

    test_make = "test_make"
    test_model = "test_model"

    empty_exifedit = ExifEdit(filename)

    empty_exifedit.add_camera_make_model(test_make, test_model)
    empty_exifedit.write(EMPTY_EXIF_FILE_TEST)

    exif_data = load_exif()
    test_obj.assertEqual((test_make, test_model),
                         (exif_data[EXIF_PRIMARY_TAGS_DICT['Make']],
                          exif_data[EXIF_PRIMARY_TAGS_DICT['Model']]))
예제 #12
0
def add_dop_general(test_obj, filename):

    test_dop = 10.5
    test_dop_precision = 100

    empty_exifedit = ExifEdit(filename)

    empty_exifedit.add_dop(test_dop, test_dop_precision)
    empty_exifedit.write(EMPTY_EXIF_FILE_TEST)

    exif_data = load_exif()
    test_obj.assertEqual((test_dop * test_dop_precision, test_dop_precision),
                         exif_data[EXIF_PRIMARY_TAGS_DICT['GPSInfo']][
                             EXIF_GPS_TAGS_DICT['GPSDOP']])
예제 #13
0
def add_altitude_general(test_obj, filename):

    test_altitude = 15.5
    test_altitude_precision = 100

    empty_exifedit = ExifEdit(filename)

    empty_exifedit.add_altitude(test_altitude, test_altitude_precision)
    empty_exifedit.write(EMPTY_EXIF_FILE_TEST)

    exif_data = load_exif()
    test_obj.assertEqual(
        (test_altitude * test_altitude_precision, test_altitude_precision),
        exif_data[EXIF_PRIMARY_TAGS_DICT['GPSInfo']][
            EXIF_GPS_TAGS_DICT['GPSAltitude']])
예제 #14
0
def add_direction_general(test_obj, filename):

    test_direction = 1
    test_direction_ref = "T"
    test_direction_precision = 100

    empty_exifedit = ExifEdit(filename)

    empty_exifedit.add_direction(test_direction, test_direction_ref,
                                 test_direction_precision)
    empty_exifedit.write(EMPTY_EXIF_FILE_TEST)

    exif_data = load_exif()
    test_obj.assertEqual(
        (test_direction * test_direction_precision, test_direction_precision),
        exif_data[EXIF_PRIMARY_TAGS_DICT['GPSInfo']][
            EXIF_GPS_TAGS_DICT['GPSImgDirection']])
예제 #15
0
def add_exif_using_timestamp(filename, start_time, offset_time):
    '''
    Add timestamp to EXIF given start time and offset time.
    '''

    exif = ExifEdit(filename)
    t = start_time + datetime.timedelta(seconds=offset_time)
    print("setting {0} time to {1} due to offset {2}".format(
        filename, t, offset_time))

    try:
        exif.add_date_time_original(t)
        exif.write()
        print("Added timestamp {} to {}.".format(filename,
                                                 t.strftime(time_format)))
    except ValueError, e:
        print("Skipping {0}: {1}".format(filename, e))
예제 #16
0
def add_image_description_general(test_obj, filename):

    test_dictionary = {
        "key_numeric": 1,
        "key_string": "one",
        "key_list": [1, 2],
        "key_dict": {
            "key_dict1": 1,
            "key_dict2": 2
        }
    }

    empty_exifedit = ExifEdit(filename)

    empty_exifedit.add_image_description(test_dictionary)
    empty_exifedit.write(EMPTY_EXIF_FILE_TEST)

    exif_data = load_exif()
    test_obj.assertEqual(
        str(test_dictionary),
        str(exif_data[EXIF_PRIMARY_TAGS_DICT['ImageDescription']]).replace(
            '"', '\''))
예제 #17
0
    def test_add_negative_lat_lon(self):

        test_latitude = -50.5
        test_longitude = -15.5
        precision = 1e7

        empty_exifedit = ExifEdit(EMPTY_EXIF_FILE_TEST)

        empty_exifedit.add_lat_lon(test_latitude, test_longitude, precision)
        empty_exifedit.write(EMPTY_EXIF_FILE_TEST)

        exif_data = load_exif()
        self.assertEqual(
            (decimal_to_dms(abs(test_latitude), precision),
             decimal_to_dms(abs(test_longitude), precision), "S", "W"),
            (exif_data[EXIF_PRIMARY_TAGS_DICT['GPSInfo']][
                EXIF_GPS_TAGS_DICT['GPSLatitude']],
             exif_data[EXIF_PRIMARY_TAGS_DICT['GPSInfo']][
                 EXIF_GPS_TAGS_DICT['GPSLongitude']],
             exif_data[EXIF_PRIMARY_TAGS_DICT['GPSInfo']][
                 EXIF_GPS_TAGS_DICT['GPSLatitudeRef']],
             exif_data[EXIF_PRIMARY_TAGS_DICT['GPSInfo']][
                 EXIF_GPS_TAGS_DICT['GPSLongitudeRef']]))
예제 #18
0
def add_lat_lon_general(test_obj, filename):

    test_latitude = 50.5475894785
    test_longitude = 15.595866685
    precision = 1e7

    empty_exifedit = ExifEdit(filename)

    empty_exifedit.add_lat_lon(test_latitude, test_longitude, precision)
    empty_exifedit.write(EMPTY_EXIF_FILE_TEST)

    exif_data = load_exif()
    test_obj.assertEqual(
        (decimal_to_dms(abs(test_latitude), precision),
         decimal_to_dms(abs(test_longitude), precision), "N", "E"),
        (exif_data[EXIF_PRIMARY_TAGS_DICT['GPSInfo']][
            EXIF_GPS_TAGS_DICT['GPSLatitude']],
         exif_data[EXIF_PRIMARY_TAGS_DICT['GPSInfo']][
             EXIF_GPS_TAGS_DICT['GPSLongitude']],
         exif_data[EXIF_PRIMARY_TAGS_DICT['GPSInfo']][
             EXIF_GPS_TAGS_DICT['GPSLatitudeRef']],
         exif_data[EXIF_PRIMARY_TAGS_DICT['GPSInfo']][
             EXIF_GPS_TAGS_DICT['GPSLongitudeRef']]))
def test_run(image_path):
    '''
    Test run for images
    '''
    s = Sequence(image_path, check_exif=False)
    file_list = s.get_file_list(image_path)
    num_image = len(file_list)

    t1 = datetime.datetime.strptime('2000_09_03_12_00_00', '%Y_%m_%d_%H_%M_%S')
    t2 = datetime.datetime.strptime('2000_09_03_12_30_00', '%Y_%m_%d_%H_%M_%S')

    p1 = point(0.5, 0.5, 0.2, t1, num_image-2)
    p2 = point(0.55, 0.55, 0.0, t2, 0)

    inter_points = interpolate_with_anchors([p1, p2], angle_offset=-90.0)

    save_path = os.path.join(image_path, 'processed')
    lib.io.mkdir_p(save_path)

    assert(len(inter_points)==len(file_list))

    for f, p in zip(file_list, inter_points):
        meta = ExifEdit(f)
        meta.add_lat_lon(p[1], p[2])
        meta.add_altitude(p[3])
        meta.add_date_time_original(p[0])
        meta.add_orientation(1)
        meta.add_direction(p[4])
        meta.write()
예제 #20
0
        bearings = s.interpolate_direction()

    for filename in s.get_file_list(args.path):
        stat = os.stat(filename)
        exifRead = EXIF(filename)
        mapillaryTag = json.loads(exifRead.extract_image_description())

        if args.interpolate:
            bearing = bearings[filename]
        else:
            bearing = exifRead.extract_direction()

        if args.offset:
            bearing = offset_bearing(bearing, args.offset)

        exifEdit = ExifEdit(filename)

        if args.interpolate or args.offset:
            exifEdit.add_direction(bearing, precision=10)
            if (args.backup):
                if 'backup' not in mapillaryTag: mapillaryTag['backup'] = {}
                if 'MAPCompassHeading' not in mapillaryTag['backup']:
                    mapillaryTag['backup']['MAPCompassHeading'] = {}
                mapillaryTag['backup']['MAPCompassHeading'][
                    'TrueHeading'] = mapillaryTag['MAPCompassHeading'][
                        'TrueHeading']
            mapillaryTag['MAPCompassHeading']['TrueHeading'] = round(
                bearing, 1)

        if args.orientation is not None:
            exifEdit.add_orientation(exifOrientation)
            try: 
                capture_time = exif.extract_capture_time()
            except Exception as e:
                print "Datetime error '{}' for image {}. Skipping".format(e, photo_file)
                shutil.move(photo_file, os.path.join(failed_folder, os.path.basename(photo_file)))
                num_exif_error += 1
                continue

            if capture_time == 0:
                # Use upload time + 12:00:00 instead
                upload_time = p["upload_date"] + " 12:00:00"
                capture_time = datetime.datetime.strptime(upload_time, "%d %B %Y %H:%M:%S")
                print("Image {} missing time stamp. Using update date instead.".format(photo_file))
                num_missing_date += 1

            exifedit = ExifEdit(photo_file)
            exifedit.add_lat_lon(p["latitude"], p["longitude"])
            exifedit.add_altitude(p.get("altitude", 0))
            exifedit.add_date_time_original(capture_time)
            exifedit.write()
            valid_files.append(photo_file)

    # Sequence Cut
    s = sequence.Sequence(image_path, skip_subfolders=True)
    sequences = s.split(move_files=False, cutoff_distance=100)
    sequence_ids = {}
    for s in sequences:
        sequence_uuid = str(uuid.uuid4())
        for im in s:
            sequence_ids[im] = sequence_uuid
예제 #22
0
        sys.exit()

    if path.lower().endswith(".jpg"):
        # single file
        file_list = [path]
    else:
        # folder(s)
        file_list = []
        for root, sub_folders, files in os.walk(path):
            file_list += [
                os.path.join(root, filename) for filename in files
                if filename.lower().endswith(".jpg")
            ]

    num_file = len(file_list)
    for i, filepath in enumerate(file_list):
        exif = EXIF(filepath)
        description_ = exif.extract_image_description()
        exif_edit = ExifEdit(filepath)
        try:
            description_ = json.loads(description_)
        except:
            description_ = {}

        if 'MAPSettingsProject' not in description_ or overwrite:
            description_['MAPSettingsProject'] = project_key
            description_ = {}
            exif_edit.add_image_description(description_)
            exif_edit.write()

    print("Done, processed %s files" % len(file_list))
예제 #23
0
    def test_add_time_original_to_existing_exif(self):

        test_altitude = 15.5
        test_altitude_precision = 100

        empty_exifedit = ExifEdit(EMPTY_EXIF_FILE_TEST)

        empty_exifedit.add_altitude(test_altitude, test_altitude_precision)
        empty_exifedit.write(EMPTY_EXIF_FILE_TEST)

        test_datetime = datetime.datetime(2016, 9, 30, 8, 29, 26, 249000)

        not_empty_exifedit = ExifEdit(EMPTY_EXIF_FILE_TEST)

        not_empty_exifedit.add_date_time_original(test_datetime)
        not_empty_exifedit.write(EMPTY_EXIF_FILE_TEST)

        exif_data = load_exif()
        self.assertEqual(
            (test_altitude * test_altitude_precision, test_altitude_precision),
            exif_data[EXIF_PRIMARY_TAGS_DICT['GPSInfo']][
                EXIF_GPS_TAGS_DICT['GPSAltitude']])
예제 #24
0
def write_metadata(image_lists):
    """
    Write the exif metadata in the jpeg file
    :param image_lists : A list in list of New_Picture_infos namedtuple
    """
    for image_list in image_lists:
        for image in image_list:
            # metadata = pyexiv2.ImageMetadata(image.path)
            metadata = ExifEdit(image.path)
            # metadata.read()
            metadata.add_date_time_original(image.New_DateTimeOriginal)
            # metadata.add_subsec_time_original(image.New_SubSecTimeOriginal)
            metadata.add_lat_lon(image.Latitude, image.Longitude)
            metadata.add_direction(image.ImgDirection)
            if image.Ele is not None:
                metadata.add_altitude(image.Ele)
            metadata.write()
            print('Writing new timestamp to ', image.path)
예제 #25
0
                    photo_file,
                    os.path.join(failed_folder, os.path.basename(photo_file)))
                num_exif_error += 1
                continue

            if capture_time == 0:
                # Use upload time + 12:00:00 instead
                upload_time = p["upload_date"] + " 12:00:00"
                capture_time = datetime.datetime.strptime(
                    upload_time, "%d %B %Y %H:%M:%S")
                print(
                    "Image {} missing time stamp. Using update date instead.".
                    format(photo_file))
                num_missing_date += 1

            exifedit = ExifEdit(photo_file)
            exifedit.add_lat_lon(p["latitude"], p["longitude"])
            exifedit.add_altitude(p.get("altitude", 0))
            exifedit.add_date_time_original(capture_time)
            exifedit.write()
            valid_files.append(photo_file)

    # Sequence Cut
    s = sequence.Sequence(image_path, skip_subfolders=True)
    sequences = s.split(move_files=False, cutoff_distance=100)
    sequence_ids = {}
    for s in sequences:
        sequence_uuid = str(uuid.uuid4())
        for im in s:
            sequence_ids[im] = sequence_uuid
예제 #26
0
    for filename in s.get_file_list(args.path):
        stat = os.stat(filename)
        exifRead = EXIF(filename)
        mapillaryTag = json.loads(exifRead.tags['Image ImageDescription'].values)
        # print filename, exifRead.extract_orientation(), mapillaryTag['MAPCameraRotation']

        if args.interpolate:
            bearing = bearings[filename];
        else:
            bearing = exifRead.extract_direction();

        if args.offset:
            bearing = offset_bearing(bearing, args.offset)

        exifEdit = ExifEdit(filename)

        if args.interpolate or args.offset:
            exifEdit.add_direction(bearing, precision=10)
            if (args.backup):
                if 'backup' not in mapillaryTag: mapillaryTag['backup'] = {}
                if 'MAPCompassHeading' not in mapillaryTag['backup']: mapillaryTag['backup']['MAPCompassHeading'] = {}
                mapillaryTag['backup']['MAPCompassHeading']['TrueHeading'] = mapillaryTag['MAPCompassHeading']['TrueHeading']
            mapillaryTag['MAPCompassHeading']['TrueHeading'] = round(bearing, 1)

        if args.orientation is not None:
            exifEdit.add_orientation(exifOrientation)

            if (args.backup and (mapillaryTag['MAPCameraRotation'] != str(args.orientation))):
                if 'backup' not in mapillaryTag: mapillaryTag['backup'] = {}
                mapillaryTag['backup']['MAPCameraRotation'] = mapillaryTag['MAPCameraRotation']