To powinno dać ci słownik indeksowany przez znaczniki numeryczne EXIF. Jeśli chcesz, aby słownik był indeksowany przez rzeczywiste ciągi nazw znaczników EXIF, spróbuj czegoś takiego:
import PIL.ExifTags
exif ={
PIL.ExifTags.TAGS[k]: v
for k, v in img._getexif().items()if k in PIL.ExifTags.TAGS
}
@Clayton dla obu obrazów, exifread zwraca pusty słownik. Ale przetestowałem na moich zdjęciach i działa dobrze.
tnq177
Otrzymuję również pusty słownik na zestaw obrazów. Czy ktoś może skomentować, dlaczego tak się dzieje? Z jakimi rodzajami obrazów działa metoda exifread.process_file ()?
Lepiej możesz odwrócić TAGI za pomocą, name2tagnum = dict((name, num) for num, name in TAGS.iteritems())a następnie to zrobić name2tagnum['ExposureTime'].
Ben
7
W przypadku Pythona 3 zmień exif.iteritems()naexif.items()
SPRBRN
14
Dla Python3.x i uruchomieniem Pillow==6.0.0, Imageobiekty stanowią obecnie getexif()metodę, która zwraca <class 'PIL.Image.Exif'>lub Nonejeśli obraz nie ma danych EXIF.
getexif()został dodany, co zwraca Exifinstancję. Wartości można pobierać i ustawiać jak słownik. Podczas zapisywania JPEG, PNG lub WEBP instancję można przekazać jako exifargument, aby uwzględnić wszelkie zmiany w obrazie wyjściowym.
Dane Exifwyjściowe można po prostu rzutować na plik dict, dzięki czemu do danych EXIF można uzyskać dostęp jako zwykłe pary klucz-wartość pliku dict. Klucze to 16-bitowe liczby całkowite, które można odwzorować na ich nazwy łańcuchowe za pomocą ExifTags.TAGSmodułu.
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'# ...
U mnie to nie działa, widzę tylko dane exif przy użyciu metody .info w formacie binarnym
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)
Odkryłem, że używanie ._getexifnie działa w wyższych wersjach Pythona, ponadto jest to klasa chroniona i należy jej unikać, jeśli to możliwe. Po przeszukaniu debugera okazało się, że jest to najlepszy sposób na uzyskanie danych EXIF dla obrazu:
from PIL importImagedef get_exif(path):returnImage.open(path).info['parsed_exif']
Zwraca słownik wszystkich danych EXIF obrazu.
Uwaga: w przypadku Python3.x użyj Pillow zamiast PIL
Odpowiedzi:
Spróbuj tego:
To powinno dać ci słownik indeksowany przez znaczniki numeryczne EXIF. Jeśli chcesz, aby słownik był indeksowany przez rzeczywiste ciągi nazw znaczników EXIF, spróbuj czegoś takiego:
źródło
import ExifTags
(bezPIL
prefiksu).Możesz także skorzystać z modułu ExifRead :
źródło
Używam tego:
lub uzyskać konkretne pole:
źródło
name2tagnum = dict((name, num) for num, name in TAGS.iteritems())
a następnie to zrobićname2tagnum['ExposureTime']
.exif.iteritems()
naexif.items()
Dla Python3.x i uruchomieniem
Pillow==6.0.0
,Image
obiekty stanowią obecniegetexif()
metodę, która zwraca<class 'PIL.Image.Exif'>
lubNone
jeśli obraz nie ma danych EXIF.Z informacji o wydaniu Pillow 6.0.0 :
Dane
Exif
wyjściowe można po prostu rzutować na plikdict
, dzięki czemu do danych EXIF można uzyskać dostęp jako zwykłe pary klucz-wartość plikudict
. Klucze to 16-bitowe liczby całkowite, które można odwzorować na ich nazwy łańcuchowe za pomocąExifTags.TAGS
modułu.Testowane z Pythonem 3.6.8 i
Pillow==6.0.0
.źródło
źródło
Odkryłem, że używanie
._getexif
nie działa w wyższych wersjach Pythona, ponadto jest to klasa chroniona i należy jej unikać, jeśli to możliwe. Po przeszukaniu debugera okazało się, że jest to najlepszy sposób na uzyskanie danych EXIF dla obrazu:Zwraca słownik wszystkich danych EXIF obrazu.
Uwaga: w przypadku Python3.x użyj Pillow zamiast PIL
źródło
info['parsed_exif']
wymaga Pillow 6.0 lub nowszej.info['exif']
jest dostępny w wersji 5.4, ale jest to test nieprzetworzony.info['parsed_exif']
w wersji 7.0.0; tylkoinfo['exif']
.Oto ten, który może być trochę łatwiejszy do odczytania. Mam nadzieję, że to jest pomocne.
źródło
Zwykle używam pyexiv2 do ustawiania informacji exif w plikach JPG, ale kiedy importuję bibliotekę w skrypcie, skrypt QGIS ulega awarii.
Znalazłem rozwiązanie korzystając z biblioteki exif:
https://pypi.org/project/exif/
Jest tak łatwy w użyciu, a dzięki Qgis nie mam żadnego problemu.
W tym kodzie wstawiam współrzędne GPS do migawki ekranu:
źródło