This is also my own memo. You can do it easily with python. As a caveat
--Latitude and longitude are degrees, minutes and seconds, so 60-ary --Values are fractions, not real numbers. (Is it a rational number?)
There are several related libraries. It is better to unify it to one of them, but it is a memo that worked for the time being. (Hey)
I found the following documents.
-Image file format standard for digital still cameras Exif 2.3
According to this, GPS Info IFD seems to be defined as follows.
There are many, but the files I dealt with were only tags 0-6. I was able to read and write the latitude, longitude, and height of GPS, so it was enough for the time being. Here, GPS Latitude Ref uses a single letter'N'or'S' to indicate north latitude or south latitude. GPS Latitude is expressed as a fraction.
I used [Pillow](9 https://pypi.org/project/Pillow/). I don't remember if I had a hard time preparing.
pip3 install pillow
I could read the latitude and longitude below.
read_gpsexif.py
from PIL import Image
infile = "test.JPG"
img = Image.open( infile )
exif = img._getexif()
for k, v in exif.items():
if k==34853:
print(v)
with this
{0: b'\x02\x00\x00\x00',
1: 'N',
2: (35.0, 20.0, 53.51123),
3: 'E',
4: (137.0, 9.0, 17.83123),
5: b'\x00', 6: 256.123}
You will get results like You can see the meaning by comparing it with the definition of GPS INfo IFD in the previous specification. Since it is degrees, minutes, and seconds, conversion is required to convert it to decimal. For example
deg,minu,sec = 35.0, 20.0, 53.51366
deg + minu/60.0 + sec/3600.0
To get `` `35.34819823888889```.
I used piexif. It is a strategy to read and rewrite Gps exif with conversion to degrees, minutes, seconds and fractions as a function.
def _to_deg(value, loc):
if value < 0:
loc_value = loc[0]
elif value > 0:
loc_value = loc[1]
else:
loc_value = ""
abs_value = abs(value)
deg = int(abs_value)
t1 = (abs_value-deg)*60
minu = int(t1)
sec = round((t1 - minu)* 60, 5)
return (deg, min, sec, loc_value)
import Fraction
def _change_to_rational(number):
f = Fraction(str(number))
return (f.numerator, f.denominator)
To do the following:
write_gpsexif.py
import piexif
lat, lng, altitude = 39.123, 139.123, 50.123
jpg_filepath = "test.JPG"
lat_deg = to_deg(lat, ["S", "N"])
lng_deg = to_deg(lng, ["W", "E"])
exif_lat = (change_to_rational(lat_deg[0]), change_to_rational(lat_deg[1]), change_to_rational(lat_deg[2]))
exif_lng = (change_to_rational(lng_deg[0]), change_to_rational(lng_deg[1]), change_to_rational(lng_deg[2]))
gps_ifd = {
piexif.GPSIFD.GPSVersionID: (2, 0, 0, 0),
piexif.GPSIFD.GPSAltitudeRef: 0,
piexif.GPSIFD.GPSAltitude: change_to_rational(round(altitude, 3)),
piexif.GPSIFD.GPSLatitudeRef: lat_deg[3],
piexif.GPSIFD.GPSLatitude: exif_lat,
piexif.GPSIFD.GPSLongitudeRef: lng_deg[3],
piexif.GPSIFD.GPSLongitude: exif_lng,
}
gps_exif = {"GPS": gps_ifd}
exif_data = piexif.load(jpg_filepath)
exif_data.update(gps_exif)
exif_bytes = piexif.dump(exif_data)
piexif.insert(exif_bytes, file_name)
I think I referred to StackOverflow for this, but I lost the link. If you find it, add it.
This is a memo when I read and write GPSExif in the photo as needed.
--I used Pillow and piexif, but somehow it seems better to unify them and use them correctly.
It was a post saying that it is a work memo of Eiya, so I would like to expand it. It's been messy lately. .. ^^; (2020/08/08)
Recommended Posts