Esto debería darle un diccionario indexado por etiquetas numéricas EXIF. Si desea que el diccionario sea indexado por las cadenas de nombre de etiqueta EXIF reales, intente algo como:
import PIL.ExifTags
exif ={
PIL.ExifTags.TAGS[k]: v
for k, v in img._getexif().items()if k in PIL.ExifTags.TAGS
}
@Clayton para ambas imágenes, exifread devuelve un diccionario vacío. Pero probé en mis fotos y funciona bien.
tnq177
También recibo un diccionario vacío para un conjunto de imágenes. ¿Alguien puede comentar por qué este es el caso? ¿Con qué tipo de imágenes funciona exifread.process_file ()?
Mejor, puedes revertir TAGS con name2tagnum = dict((name, num) for num, name in TAGS.iteritems())y luego hacerlo name2tagnum['ExposureTime'].
Ben
77
Para Python 3, cambie exif.iteritems()aexif.items()
SPRBRN
14
Para Python3.xy comenzar Pillow==6.0.0, los Imageobjetos ahora proporcionan un getexif()método que devuelve <class 'PIL.Image.Exif'>o Nonesi la imagen no tiene datos EXIF.
getexif()se ha agregado, lo que devuelve una Exifinstancia. Los valores se pueden recuperar y establecer como un diccionario. Al guardar JPEG, PNG o WEBP, la instancia se puede pasar como exifargumento para incluir cualquier cambio en la imagen de salida.
La Exifsalida simplemente se puede convertir a a dict, de modo que se pueda acceder a los datos EXIF como pares clave-valor regulares de a dict. Las claves son enteros de 16 bits que pueden asignarse a sus nombres de cadena utilizando el ExifTags.TAGSmódulo.
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'# ...
No me funciona, solo puedo ver los datos exif usando el método .info en binario
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)
He descubierto que el uso ._getexifno funciona en versiones superiores de Python, además, es una clase protegida y uno debería evitar usarlo si es posible. Después de buscar en el depurador, esta es la mejor forma de obtener los datos EXIF para una imagen:
from PIL importImagedef get_exif(path):returnImage.open(path).info['parsed_exif']
Esto devuelve un diccionario de todos los datos EXIF de una imagen.
Respuestas:
Prueba esto:
Esto debería darle un diccionario indexado por etiquetas numéricas EXIF. Si desea que el diccionario sea indexado por las cadenas de nombre de etiqueta EXIF reales, intente algo como:
fuente
import ExifTags
(sin elPIL
prefijo).También puede usar el módulo ExifRead :
fuente
Yo uso esto:
o para obtener un campo específico:
fuente
name2tagnum = dict((name, num) for num, name in TAGS.iteritems())
y luego hacerloname2tagnum['ExposureTime']
.exif.iteritems()
aexif.items()
Para Python3.xy comenzar
Pillow==6.0.0
, losImage
objetos ahora proporcionan ungetexif()
método que devuelve<class 'PIL.Image.Exif'>
oNone
si la imagen no tiene datos EXIF.De las notas de la versión de Pillow 6.0.0 :
La
Exif
salida simplemente se puede convertir a adict
, de modo que se pueda acceder a los datos EXIF como pares clave-valor regulares de adict
. Las claves son enteros de 16 bits que pueden asignarse a sus nombres de cadena utilizando elExifTags.TAGS
módulo.Probado con Python 3.6.8 y
Pillow==6.0.0
.fuente
fuente
He descubierto que el uso
._getexif
no funciona en versiones superiores de Python, además, es una clase protegida y uno debería evitar usarlo si es posible. Después de buscar en el depurador, esta es la mejor forma de obtener los datos EXIF para una imagen:Esto devuelve un diccionario de todos los datos EXIF de una imagen.
Nota: Para Python3.x use Pillow en lugar de PIL
fuente
info['parsed_exif']
requiere Pillow 6.0 o más reciente.info['exif']
está disponible en 5.4, pero esta es una cadena de bytes sin procesar.info['parsed_exif']
en la versión 7.0.0; solamenteinfo['exif']
.Aquí está el que puede ser un poco más fácil de leer. Espero que esto sea útil.
fuente
Usualmente uso pyexiv2 para configurar información exif en archivos JPG, pero cuando importo la biblioteca en un script QGIS se bloquea.
Encontré una solución usando la biblioteca exif:
https://pypi.org/project/exif/
Es muy fácil de usar, y con Qgis no tengo ningún problema.
En este código inserto coordenadas GPS en una instantánea de la pantalla:
fuente