Перезаписать GPS-координаты в Image Exif с помощью Python 3.6
Я пытаюсь преобразовать геотеги изображений так, чтобы изображения и наземные контрольные точки находились в одной и той же системе координат внутри моего программного обеспечения (картограф Pix4D).
Ответ здесь говорит:
Данные Exif стандартизированы, а данные GPS должны быть закодированы с использованием географических координат (минут, секунд и т. Д.), Описанных выше, а не дроби. Если он не закодирован в этом формате в теге exif, он не будет прикреплен.
Вот мой код:
import os, piexif, pyproj
from PIL import Image
img = Image.open(os.path.join(dirPath,fn))
exif_dict = piexif.load(img.info['exif'])
breite = exif_dict['GPS'][piexif.GPSIFD.GPSLatitude]
lange = exif_dict['GPS'][piexif.GPSIFD.GPSLongitude]
breite = breite[0][0] / breite[0][1] + breite[1][0] / (breite[1][1] * 60) + breite[2][0] / (breite[2][1] * 3600)
lange = lange[0][0] / lange[0][1] + lange[1][0] / (lange[1][1] * 60) + lange[2][0] / (lange[2][1] * 3600)
print(breite) #48.81368778730952
print(lange) #9.954511162420633
x, y = pyproj.transform(wgs84, gk3, lange, breite) #from WGS84 to GaussKrüger zone 3
print(x) #3570178.732528623
print(y) #5408908.20172699
exif_dict['GPS'][piexif.GPSIFD.GPSLatitude] = [ ( (int)(round(y,6) * 1000000), 1000000 ), (0, 1), (0, 1) ]
exif_bytes = piexif.dump(exif_dict) #error here
img.save(os.path.join(outPath,fn), "jpeg", exif=exif_bytes)
Я получаю struct.error: аргумент вне диапазона в методе дампа. Оригинальный тег GPSInfo выглядит так: {0: b'\x02\x03\x00\x00', 1: 'N', 2: ((48, 1), (48, 1), (3449322402, 70000000)), 3: 'E', 4: ((9, 1), (57, 1), (1136812930, 70000000)), 5: b'\x00', 6: (3659, 10)}
Я предполагаю, что я должен сместить значения и правильно их кодировать перед записью, но понятия не имею, что делать.
1 ответ
Похоже, вы уже используете PIL и Python 3.x, но не уверены, что хотите продолжить piexif
но в любом случае вам может быть проще сначала преобразовать градусы, минуты и секунды в десятичную. Похоже, вы уже пытаетесь это сделать, но если поместить его в отдельную функцию, это может быть более понятным и учитывает направление.
Вот пример:
def get_decimal_from_dms(dms, ref):
degrees = dms[0][0] / dms[0][1]
minutes = dms[1][0] / dms[1][1] / 60.0
seconds = dms[2][0] / dms[2][1] / 3600.0
if ref in ['S', 'W']:
degrees = -degrees
minutes = -minutes
seconds = -seconds
return round(degrees + minutes + seconds, 5)
def get_coordinates(geotags):
lat = get_decimal_from_dms(geotags['GPSLatitude'], geotags['GPSLatitudeRef'])
lon = get_decimal_from_dms(geotags['GPSLongitude'], geotags['GPSLongitudeRef'])
return (lat,lon)
geotags
в этом примере это словарь с GPSTAGS в качестве ключей вместо цифровых кодов для удобства чтения. Вы можете найти более подробную информацию и полный пример из этого поста в блоге: Начало работы с геокодированием метаданных изображения Exif в Python 3
После долгой подшивки и перетягивания я добрался до страниц библиотеки манипулирования метаданными изображений py3exiv2. При чтении можно найти исчерпывающие списки тегов метаданных, но вот список тегов EXIF, чтобы сэкономить несколько кликов.
Он без проблем работает в Linux и предоставляет множество возможностей для редактирования заголовков изображений. Документация также довольно ясна. Я рекомендую это как решение, и мне интересно узнать, решает ли оно и проблемы всех остальных.