1

How can I write full gps coordinates in degrees, minutes, seconds format as a GPS exif tag to .tif images using python? I can write a portion of the gps coord using the piexif package (e.g. Longitude) if I only include the decimal and minutes as integers. However piexif throws a ValueError whenever I include seconds and fractions of a second. piexif will only accept a tuple containing two integers for the longitude, despite the standard calling for 3 integers.

Info on EXIF tags is available [here](http://www.cipa.jp/std/documents/e/DC- 008-2012_E.pdf)!

import piexif  # pip install piexif
from PIL import Image #  PIL version 4.0.0 for compatability with conda/py3.6
    
fname = "foo.tiff"

#read tiff file into a pillow image obj
im = Image.open(fname)
#readin any existing exif data to a dict
exif_dict = piexif.load(fname)

#GPS coord to write to GPS tag in dms format
#long = 120° 37' 42.9996" East longitude
LongRef = "E"
Long_d = 120
Long_m = 37
Long_s = 42.9996

#add gps data to EXIF containing GPS dict
#exif_dict['GPS'][piexif.GPSIFD.GPSLongitude] = (Long_d, Long_m) #this works
exif_dict['GPS'][piexif.GPSIFD.GPSLongitude] = (Long_d, (Long_m,Long_s)) #this returns an error
exif_dict['GPS'][piexif.GPSIFD.GPSLongitude] = (Long_d, Long_m, Long_s) #this also returns an error
"""
Traceback (most recent call last):

  File "<ipython-input-210-918cd4e2989f>", line 7, in <module>
    exif_bytes = piexif.dump(exif_dict)

  File "C:\Users\JF\AppData\Local\Continuum\anaconda3\lib\site-packages\piexif-1.0.13-py3.6.egg\piexif\_dump.py", line 74, in dump
    gps_set = _dict_to_bytes(gps_ifd, "GPS", zeroth_length + exif_length)

  File "C:\Users\JF\AppData\Local\Continuum\anaconda3\lib\site-packages\piexif-1.0.13-py3.6.egg\piexif\_dump.py", line 341, in _dict_to_bytes
    '{0} in {1} IFD. Got as {2}.'.format(key, ifd, type(ifd_dict[key]))

ValueError: "dump" got wrong type of exif value.
4 in GPS IFD. Got as <class 'tuple'>.
"""

#convert updated GPS dict to exif_bytes
exif_bytes = piexif.dump(exif_dict)

#encode updated exif tag into image and save as a jpeg
im.save(fname.replace('.tiff','.jpeg'), "jpeg", exif=exif_bytes)
Community
  • 1
  • 1
John Saraceno
  • 229
  • 3
  • 11

2 Answers2

3

Found this solution, There is great documentation here!!

http://www.cipa.jp/std/documents/e/DC-008-2012_E.pdf

https://piexif.readthedocs.io/en/latest/functions.html

Hope this is useful

import piexif 
#http://www.cipa.jp/std/documents/e/DC-008-2012_E.pdf
#https://piexif.readthedocs.io/en/latest/functions.html

exif_dict = piexif.load("test_exif.JPG")


gps_ifd = {piexif.GPSIFD.GPSLatitudeRef:"N",
           piexif.GPSIFD.GPSLatitude:(2,2),
           piexif.GPSIFD.GPSLongitudeRef:"W",
           piexif.GPSIFD.GPSLongitude:(1,1),
           piexif.GPSIFD.GPSAltitudeRef:(0),
           piexif.GPSIFD.GPSAltitude:(1700,1)
           }

exif_dict = {"0th":{}, "Exif":{}, "GPS":gps_ifd, "1st":{}, "thumbnail":None}
exif_bytes = piexif.dump(exif_dict)
piexif.insert(exif_bytes,"test_exif.JPG")
exif_dict = piexif.load("test_exif.JPG")
print(exif_dict)
2

I haven't used piexif but according to their docs you need to specify the data in rational format as in (int, int):

exif_dict["GPS"][piexif.GPSIFD.GPSLongitude] = [(120, 1), (37,1), (429996, 10000)];

Basically use (numerator, denominator) to describe your values with integers.

Ionut Ticus
  • 2,683
  • 2
  • 17
  • 25