Это должно дать вам словарь, проиндексированный числовыми тегами EXIF. Если вы хотите, чтобы словарь был проиндексирован фактическими строками имен тегов EXIF, попробуйте что-нибудь вроде:
import PIL.ExifTags
exif ={
PIL.ExifTags.TAGS[k]: v
for k, v in img._getexif().items()if k in PIL.ExifTags.TAGS
}
@Clayton для обоих изображений, exifread возвращает пустой словарь. Но я протестировал на своих фотографиях, и все работает нормально.
tnq177
Я также получаю пустой словарь для набора изображений. Может ли кто-нибудь прокомментировать, почему это так? С какими изображениями работает exifread.process_file ()?
Лучше всего поменять местами ТЕГИ с помощью, name2tagnum = dict((name, num) for num, name in TAGS.iteritems())а затем сделать name2tagnum['ExposureTime'].
Бен
7
Для Python 3 измените exif.iteritems()наexif.items()
SPRBRN
14
Для Python3.x и запуска Pillow==6.0.0, Imageобъекты в настоящее время обеспечивают getexif()метод , который возвращает <class 'PIL.Image.Exif'>или , Noneесли изображение не имеет данных EXIF.
getexif()был добавлен, который возвращает Exifэкземпляр. Значения можно получить и установить как словарь. При сохранении JPEG, PNG или WEBP экземпляр можно передать в качестве exifаргумента для включения любых изменений в выходное изображение.
ExifВыход может быть просто отливают к dict, так что данные EXIF могут быть доступны как обычные пары ключ-значение а dict. Ключи - это 16-разрядные целые числа, которые можно сопоставить с именами строк с помощью ExifTags.TAGSмодуля.
from PIL importImage,ExifTags
img =Image.open("sample.jpg")
img_exif = img.getexif()print(type(img_exif))# <class 'PIL.Image.Exif'>if img_exif isNone:print("Sorry, image has no exif data.")else:
img_exif_dict = dict(img_exif)print(img_exif_dict)# { ... 42035: 'FUJIFILM', 42036: 'XF23mmF2 R WR', 42037: '75A14188' ... }for key, val in img_exif_dict.items():if key inExifTags.TAGS:print(f"{ExifTags.TAGS[key]}:{repr(val)}")# ExifVersion:b'0230'# ...# FocalLength:(2300, 100)# ColorSpace:1# FocalLengthIn35mmFilm:35# ...# Model:'X-T2'# Make:'FUJIFILM'# ...# DateTime:'2019:12:01 21:30:07'# ...
У меня это не работает, я могу видеть только данные exif с использованием метода .info в двоичном формате
GM
12
import sys
import PIL
import PIL.ImageasPILimagefrom PIL importImageDraw,ImageFont,ImageEnhancefrom PIL.ExifTagsimport TAGS, GPSTAGS
classWorker(object):def __init__(self, img):
self.img = img
self.exif_data = self.get_exif_data()
self.lat = self.get_lat()
self.lon = self.get_lon()
self.date =self.get_date_time()
super(Worker, self).__init__()@staticmethoddef get_if_exist(data, key):if key in data:return data[key]returnNone@staticmethoddef convert_to_degress(value):"""Helper function to convert the GPS coordinates
stored in the EXIF to degress in float format"""
d0 = value[0][0]
d1 = value[0][1]
d = float(d0)/ float(d1)
m0 = value[1][0]
m1 = value[1][1]
m = float(m0)/ float(m1)
s0 = value[2][0]
s1 = value[2][1]
s = float(s0)/ float(s1)return d +(m /60.0)+(s /3600.0)def get_exif_data(self):"""Returns a dictionary from the exif data of an PIL Image item. Also
converts the GPS Tags"""
exif_data ={}
info = self.img._getexif()if info:for tag, value in info.items():
decoded = TAGS.get(tag, tag)if decoded =="GPSInfo":
gps_data ={}for t in value:
sub_decoded = GPSTAGS.get(t, t)
gps_data[sub_decoded]= value[t]
exif_data[decoded]= gps_data
else:
exif_data[decoded]= value
return exif_data
def get_lat(self):"""Returns the latitude and longitude, if available, from the
provided exif_data (obtained through get_exif_data above)"""# print(exif_data)if'GPSInfo'in self.exif_data:
gps_info = self.exif_data["GPSInfo"]
gps_latitude = self.get_if_exist(gps_info,"GPSLatitude")
gps_latitude_ref = self.get_if_exist(gps_info,'GPSLatitudeRef')if gps_latitude and gps_latitude_ref:
lat = self.convert_to_degress(gps_latitude)if gps_latitude_ref !="N":
lat =0- lat
lat = str(f"{lat:.{5}f}")return lat
else:returnNonedef get_lon(self):"""Returns the latitude and longitude, if available, from the
provided exif_data (obtained through get_exif_data above)"""# print(exif_data)if'GPSInfo'in self.exif_data:
gps_info = self.exif_data["GPSInfo"]
gps_longitude = self.get_if_exist(gps_info,'GPSLongitude')
gps_longitude_ref = self.get_if_exist(gps_info,'GPSLongitudeRef')if gps_longitude and gps_longitude_ref:
lon = self.convert_to_degress(gps_longitude)if gps_longitude_ref !="E":
lon =0- lon
lon = str(f"{lon:.{5}f}")return lon
else:returnNonedef get_date_time(self):if'DateTime'in self.exif_data:
date_and_time = self.exif_data['DateTime']return date_and_time
if __name__ =='__main__':try:
img =PILimage.open(sys.argv[1])
image =Worker(img)
lat = image.lat
lon = image.lon
date = image.date
print(date, lat, lon)exceptExceptionas e:print(e)
Я обнаружил, что использование ._getexifне работает в более высоких версиях python, более того, это защищенный класс, и его следует по возможности избегать. Покопавшись в отладчике, я обнаружил, что это лучший способ получить данные EXIF для изображения:
from PIL importImagedef get_exif(path):returnImage.open(path).info['parsed_exif']
Это возвращает словарь всех данных EXIF изображения.
Примечание: для Python3.x используйте Pillow вместо PIL
Ответы:
Попробуй это:
Это должно дать вам словарь, проиндексированный числовыми тегами EXIF. Если вы хотите, чтобы словарь был проиндексирован фактическими строками имен тегов EXIF, попробуйте что-нибудь вроде:
источник
import ExifTags
(безPIL
префикса).Вы также можете использовать модуль ExifRead :
источник
Я использую это:
или получить конкретное поле:
источник
name2tagnum = dict((name, num) for num, name in TAGS.iteritems())
а затем сделатьname2tagnum['ExposureTime']
.exif.iteritems()
наexif.items()
Для Python3.x и запуска
Pillow==6.0.0
,Image
объекты в настоящее время обеспечиваютgetexif()
метод , который возвращает<class 'PIL.Image.Exif'>
или ,None
если изображение не имеет данных EXIF.Из примечаний к выпуску Pillow 6.0.0 :
Exif
Выход может быть просто отливают кdict
, так что данные EXIF могут быть доступны как обычные пары ключ-значение аdict
. Ключи - это 16-разрядные целые числа, которые можно сопоставить с именами строк с помощьюExifTags.TAGS
модуля.Протестировано с Python 3.6.8 и
Pillow==6.0.0
.источник
источник
Я обнаружил, что использование
._getexif
не работает в более высоких версиях python, более того, это защищенный класс, и его следует по возможности избегать. Покопавшись в отладчике, я обнаружил, что это лучший способ получить данные EXIF для изображения:Это возвращает словарь всех данных EXIF изображения.
Примечание: для Python3.x используйте Pillow вместо PIL
источник
info['parsed_exif']
требуется Pillow 6.0 или новее.info['exif']
доступен в версии 5.4, но это необработанная строка байтов.info['parsed_exif']
в версии 7.0.0; толькоinfo['exif']
.Вот тот, который будет немного легче читать. Надеюсь, это будет полезно.
источник
Обычно я использую pyexiv2 для установки информации exif в файлах JPG, но когда я импортирую библиотеку в скрипт, происходит сбой скрипта QGIS.
Я нашел решение с помощью библиотеки exif:
https://pypi.org/project/exif/
Это так просто в использовании, и с Qgis у меня нет никаких проблем.
В этом коде я вставляю координаты GPS в снимок экрана:
источник