TransWikia.com

Writing into XMP and EXIF Metadata from attribute table values in PyQGIS

Geographic Information Systems Asked on November 6, 2021

I’ve already learnt how to read EXIF and XMP data’s from JPG. Now I would like to write from value in attribute table into their XMP and EXIF tags.

This code Import EXIF / XMP , and I would like to do the opposite.

from PIL import Image
from PIL.ExifTags import TAGS, GPSTAGS
from xml.etree import ElementTree as ET

layer = iface.activeLayer()
dpr = layer.dataProvider()

layer.startEditing()
apr_ind = layer.fields().indexFromName("apr")
exp_ind  = layer.fields().indexFromName("exp")
fyd_ind = layer.fields().indexFromName("fyd")

for feature in layer.getFeatures():
    file_path = feature["photo"] 
    print(file_path)
    img = Image.open(file_path)
    exif = { TAGS[k]: v for k, v in img._getexif().items() if k in TAGS }
    with open(file_path, "rb") as f:
        s = str(f.read())
    start = s.find('<x:xmpmeta')
    end   = s.find('</x:xmpmeta')
    xmp   = s[start:end+12].replace("\n","n")
    tree  = ET.XML(xmp)
    apr = exif["FNumber"][0]/exif["FNumber"][1]
    exp = exif["ExposureBiasValue"][0]
    fyd = tree[0][0].attrib['{http://www.dji.com/drone-dji/1.0/}GimbalPitchDegree']

    dpr.changeAttributeValues({ feature.id():{apr_ind: apr,
                                            exp_ind: exp }})
layer.commitChanges()
print("COMPLETED") 

2 Answers

I usually use pyexiv2 to set exif information in JPG files, but when I import the library in a script QGIS script crash.

I found a solution using the library exif:

https://pypi.org/project/exif/

It's so easy to use, and with Qgis I don,'t have any problem.

In this code I insert GPS coordinates to a snapshot of screen:

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())

Answered by RBenet on November 6, 2021

pyexiv2 Solution:

Select layer and run the script. You have to change values to string for non-string fields using str() method. This solution is about layers which were created by ImportPhotos plugin. For other layers, you must specify the file path related to feature.

from pyexiv2 import Image

layer = iface.activeLayer()

for feature in layer.getFeatures():
    image = Image(feature["Path"]) # or Image("full_path_of_file_related_to_the_feature")
    metadata = image.read_all()

    metadata["EXIF"]["Exif.Image.Make"] = feature["Camera Mak"]
    metadata["XMP"]["Xmp.drone-dji.FlightYawDegree"] = str(feature["fyd"])
    metadata["XMP"]["Xmp.drone-dji.GimbalYawDegree"] = str(feature["gyd"])

    image.modify_all(metadata) # write new values to image file

Answered by Kadir Şahbaz on November 6, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP