Skip to content

Instantly share code, notes, and snippets.

@lightheaded
Created April 12, 2021 13:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lightheaded/f51ce2b105535db6d4d7ad3b3b50219d to your computer and use it in GitHub Desktop.
Save lightheaded/f51ce2b105535db6d4d7ad3b3b50219d to your computer and use it in GitHub Desktop.
# Usage: python shift-gps-coordinates.py /path/to/photos
import copy
import pathlib
import sys
from os import listdir
from os.path import isfile, join, basename, dirname
from shutil import copy2
import piexif
from PIL import Image
IMAGE_COORDINATE_OFFSET = 66
def get_photos_list(photos_path):
photos = []
for file_name in listdir(photos_path):
file_path = join(photos_path, file_name)
if isfile(file_path):
file_extension = file_name.split('.')[-1].lower()
if file_extension == 'jpg':
photos.append(file_path)
return photos
def get_exif(photo_path):
image = Image.open(photo_path)
exif_dict = piexif.load(image.info['exif'])
return exif_dict
def get_photo_coordinates(photo_path):
exif_dict = get_exif(photo_path)
updated_dict = copy.deepcopy(exif_dict)
lat = updated_dict['GPS'][piexif.GPSIFD.GPSLatitude]
lon = updated_dict['GPS'][piexif.GPSIFD.GPSLongitude]
alt = updated_dict['GPS'][piexif.GPSIFD.GPSAltitude]
return lat, lon, alt
def set_photo_coordinates(photo_path, lat, lon, alt):
exif_dict = get_exif(photo_path)
exif_dict['GPS'][piexif.GPSIFD.GPSLatitude] = lat
exif_dict['GPS'][piexif.GPSIFD.GPSLongitude] = lon
exif_dict['GPS'][piexif.GPSIFD.GPSAltitude] = alt
exif_bytes = piexif.dump(exif_dict)
piexif.insert(exif_bytes, photo_path)
def make_a_copy(photo_path):
file_name = basename(photo_path)
original_dir_path = dirname(photo_path)
new_dir_path = '{}/output'.format(original_dir_path)
pathlib.Path(new_dir_path).mkdir(parents=True, exist_ok=True)
new_photo_path = "{}/output/{}".format(original_dir_path, file_name)
copy2(photo_path, new_photo_path)
return new_photo_path
def main():
if len(sys.argv) != 2:
print('Please provide a directory to use as an argument to the script')
exit(1)
photos_path = sys.argv[1]
photos_list = sorted(get_photos_list(photos_path))
# 3072->3006
for i, source_file_path in enumerate(photos_list):
if i >= IMAGE_COORDINATE_OFFSET:
source_file_name = basename(source_file_path)
target_file_path = photos_list[i - IMAGE_COORDINATE_OFFSET]
target_file_name = basename(target_file_path)
copied_file_path = make_a_copy(source_file_path)
source_lat, source_lon, source_alt = get_photo_coordinates(source_file_path)
target_lat, target_lon, target_alt = get_photo_coordinates(copied_file_path)
set_photo_coordinates(copied_file_path, target_lat, target_lon, target_alt)
print('{} ({},{}) -> {} ({},{})'.format(
source_file_name,
source_lat,
source_lon,
target_file_name,
target_lat,
target_lon,
))
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment