Saya menggunakan PIL. Bagaimana cara mengubah data EXIF menjadi kamus barang?
Saya menggunakan PIL. Bagaimana cara mengubah data EXIF menjadi kamus barang?
Jawaban:
Coba ini:
import PIL.Image
img = PIL.Image.open('img.jpg')
exif_data = img._getexif()
Ini akan memberi Anda kamus yang diindeks oleh tag numerik EXIF. Jika Anda ingin kamus diindeks oleh string nama tag EXIF yang sebenarnya, coba sesuatu seperti:
import PIL.ExifTags
exif = {
PIL.ExifTags.TAGS[k]: v
for k, v in img._getexif().items()
if k in PIL.ExifTags.TAGS
}
import ExifTags
(tanpa PIL
awalan).
Anda juga dapat menggunakan modul ExifRead :
import exifread
# Open image file for reading (binary mode)
f = open(path_name, 'rb')
# Return Exif tags
tags = exifread.process_file(f)
Saya menggunakan ini:
import os,sys
from PIL import Image
from PIL.ExifTags import TAGS
for (k,v) in Image.open(sys.argv[1])._getexif().iteritems():
print '%s = %s' % (TAGS.get(k), v)
atau untuk mendapatkan bidang tertentu:
def get_field (exif,field) :
for (k,v) in exif.iteritems():
if TAGS.get(k) == field:
return v
exif = image._getexif()
print get_field(exif,'ExposureTime')
name2tagnum = dict((name, num) for num, name in TAGS.iteritems())
dan kemudian melakukannya name2tagnum['ExposureTime']
.
exif.iteritems()
keexif.items()
Untuk Python3.x dan awal Pillow==6.0.0
, Image
objek sekarang menyediakan getexif()
metode yang mengembalikan <class 'PIL.Image.Exif'>
atau None
jika gambar tidak memiliki data EXIF.
Dari catatan rilis Pillow 6.0.0 :
getexif()
telah ditambahkan, yang mengembalikan sebuahExif
instance. Nilai dapat diambil dan diatur seperti kamus. Saat menyimpan JPEG, PNG atau WEBP, instance dapat diteruskan sebagaiexif
argumen untuk menyertakan perubahan apa pun pada gambar output.
The Exif
keluaran hanya dapat dicor ke dict
, sehingga data EXIF kemudian dapat diakses sebagai pasangan kunci-nilai yang teratur dari dict
. Kuncinya adalah bilangan bulat 16-bit yang dapat dipetakan ke nama stringnya menggunakan ExifTags.TAGS
modul.
from PIL import Image, ExifTags
img = Image.open("sample.jpg")
img_exif = img.getexif()
print(type(img_exif))
# <class 'PIL.Image.Exif'>
if img_exif is None:
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 in ExifTags.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'
# ...
Diuji dengan Python 3.6.8 dan Pillow==6.0.0
.
import sys
import PIL
import PIL.Image as PILimage
from PIL import ImageDraw, ImageFont, ImageEnhance
from PIL.ExifTags import TAGS, GPSTAGS
class Worker(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__()
@staticmethod
def get_if_exist(data, key):
if key in data:
return data[key]
return None
@staticmethod
def 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:
return None
def 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:
return None
def 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)
except Exception as e:
print(e)
Saya telah menemukan bahwa penggunaan ._getexif
tidak berfungsi di versi python yang lebih tinggi, terlebih lagi, ini adalah kelas yang dilindungi dan seseorang harus menghindari menggunakannya jika memungkinkan. Setelah menggali di sekitar debugger, inilah yang saya temukan sebagai cara terbaik untuk mendapatkan data EXIF untuk sebuah gambar:
from PIL import Image
def get_exif(path):
return Image.open(path).info['parsed_exif']
Ini mengembalikan kamus dari semua data EXIF gambar.
Catatan: Untuk Python3.x gunakan Pillow sebagai ganti PIL
info['parsed_exif']
membutuhkan Pillow 6.0 atau yang lebih baru. info['exif']
tersedia dalam 5.4, tapi ini adalah bytestring mentah.
info['parsed_exif']
di versi 7.0.0; saja info['exif']
.
Ini salah satu yang mungkin sedikit lebih mudah dibaca. Semoga bermanfaat.
from PIL import Image
from PIL import ExifTags
exifData = {}
img = Image.open(picture.jpg)
exifDataRaw = img._getexif()
for tag, value in exifDataRaw.items():
decodedTag = ExifTags.TAGS.get(tag, tag)
exifData[decodedTag] = value
Saya biasanya menggunakan pyexiv2 untuk mengatur informasi exif dalam file JPG, tetapi ketika saya mengimpor perpustakaan dalam skrip QGIS script crash.
Saya menemukan solusi menggunakan library exif:
https://pypi.org/project/exif/
Sangat mudah digunakan, dan dengan Qgis saya tidak punya masalah.
Dalam kode ini saya memasukkan koordinat GPS ke snapshot layar:
from exif import Image
with open(file_name, 'rb') as image_file:
my_image = Image(image_file)
my_image.make = "Python"
my_image.gps_latitude_ref=exif_lat_ref
my_image.gps_latitude=exif_lat
my_image.gps_longitude_ref= exif_lon_ref
my_image.gps_longitude= exif_lon
with open(file_name, 'wb') as new_image_file:
new_image_file.write(my_image.get_file())