Isso deve fornecer um dicionário indexado por tags numéricas EXIF. Se você deseja que o dicionário seja indexado pelas cadeias de nomes de tags EXIF reais, tente 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 as imagens, exifread retorna o dicionário vazio. Mas eu testei nas minhas fotos e funciona muito bem.
tnq177
Também recebo um dicionário vazio para um conjunto de imagens. Alguém pode comentar por que esse é o caso? Com que tipo de imagens trabalha o exifread.process_file ()?
Melhor, você pode reverter TAGS com name2tagnum = dict((name, num) for num, name in TAGS.iteritems())e depois fazer name2tagnum['ExposureTime'].
Ben
7
Para Python 3, altere exif.iteritems()paraexif.items()
SPRBRN
14
Para Python3.xe inicial Pillow==6.0.0, os Imageobjetos agora fornecem um getexif()método que retorna <class 'PIL.Image.Exif'>ou Nonese a imagem não possui dados EXIF.
getexif()foi adicionado, o que retorna uma Exifinstância. Os valores podem ser recuperados e definidos como um dicionário. Ao salvar JPEG, PNG ou WEBP, a instância pode ser transmitida como um exifargumento para incluir quaisquer alterações na imagem de saída.
A Exifsaída pode simplesmente ser convertida em a dict, para que os dados EXIF possam ser acessados como pares de valores-chave regulares de a dict. As chaves são números inteiros de 16 bits que podem ser mapeados para seus nomes de sequência usando o 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'# ...
Não funciona para mim, posso ver apenas os dados exif usando o método .info em binário
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)
Eu descobri que o uso ._getexifnão funciona em versões mais altas de python; além disso, é uma classe protegida e deve-se evitar usá-lo, se possível. Depois de pesquisar o depurador, achei a melhor maneira de obter os dados EXIF de uma imagem:
from PIL importImagedef get_exif(path):returnImage.open(path).info['parsed_exif']
Isso retorna um dicionário de todos os dados EXIF de uma imagem.
Respostas:
Tente o seguinte:
Isso deve fornecer um dicionário indexado por tags numéricas EXIF. Se você deseja que o dicionário seja indexado pelas cadeias de nomes de tags EXIF reais, tente algo como:
fonte
import ExifTags
(sem oPIL
prefixo).Você também pode usar o módulo ExifRead :
fonte
Eu uso isso:
ou para obter um campo específico:
fonte
name2tagnum = dict((name, num) for num, name in TAGS.iteritems())
e depois fazername2tagnum['ExposureTime']
.exif.iteritems()
paraexif.items()
Para Python3.xe inicial
Pillow==6.0.0
, osImage
objetos agora fornecem umgetexif()
método que retorna<class 'PIL.Image.Exif'>
ouNone
se a imagem não possui dados EXIF.Das notas de versão do Pillow 6.0.0 :
A
Exif
saída pode simplesmente ser convertida em adict
, para que os dados EXIF possam ser acessados como pares de valores-chave regulares de adict
. As chaves são números inteiros de 16 bits que podem ser mapeados para seus nomes de sequência usando oExifTags.TAGS
módulo.Testado com Python 3.6.8 e
Pillow==6.0.0
.fonte
fonte
Eu descobri que o uso
._getexif
não funciona em versões mais altas de python; além disso, é uma classe protegida e deve-se evitar usá-lo, se possível. Depois de pesquisar o depurador, achei a melhor maneira de obter os dados EXIF de uma imagem:Isso retorna um dicionário de todos os dados EXIF de uma imagem.
Nota: Para Python3.x, use Pillow em vez de PIL
fonte
info['parsed_exif']
requer Pillow 6.0 ou mais recente.info['exif']
está disponível na 5.4, mas essa é uma restrição de bytes bruta.info['parsed_exif']
na versão 7.0.0; somenteinfo['exif']
.Aqui está o que pode ser um pouco mais fácil de ler. Espero que isso seja útil.
fonte
Normalmente, uso pyexiv2 para definir informações exif em arquivos JPG, mas quando importo a biblioteca em uma falha de script QGIS de script.
Encontrei uma solução usando a biblioteca exif:
https://pypi.org/project/exif/
É tão fácil de usar, e com o Qgis eu não tenho nenhum problema.
Neste código, insiro coordenadas GPS em um instantâneo da tela:
fonte