[Python]读写照片位置信息标签(JPG文件GPS Exif)


介绍

这也是给我的备忘录。您可以使用python轻松实现。请注意,

  • 纬度/经度是度,分,秒,所以60进制
  • 值是分数,不是实数。 (这是一个有理数吗?)

有几个相关的库。最好将其与其中一个统一,但这是暂时有效的备忘录。 (嘿)

规格?

我找到了以下文件。

  • 数码相机Exif 2.3的图像文件格式标准

据此,GPS Info IFD似乎定义如下。

image.png

有很多,但是在我处理的文件中,只有标签0-6。我能够读写GPS的纬度,经度和高度,所以暂时就足够了。在这里,GPS纬度参考使用单个字母" N"或" S"来表示北纬或南纬。 GPS纬度表示为分数。

用python读写

使用枕头

读取纬度和经度

我使用了

枕头。我不记得我是否很难准备。

1
pip3 install pillow

我可以阅读下面的纬度和经度。

read_gpsexif.py

1
2
3
4
5
6
7
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)

现在

1
2
3
4
5
6
{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}

您将得到类似

的结果。通过将其与先前规范中的GPS INfo IFD定义进行比较,可以看到其含义。由于它是度,分和秒,因此需要转换才能将其转换为十进制。例如

1
2
deg,minu,sec = 35.0, 20.0, 53.51366
deg + minu/60.0 + sec/3600.0

获取35.34819823888889

使用piexif

重写GPS Exif纬度/经度

我用过piexif。
这是一种读取和重写Gps exif的策略,并将其转换为度,分,秒和分数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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)

使用

执行以下操作:

write_gpsexif.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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)

我想我使用StackOverflow作为参考,但是我丢失了链接。如果找到它,添加它。

摘要?杂项印象

这是根据需要在照片中读写GPSExif时的备忘。

  • 我使用了Pillow和piexif,但是以某种方式将它们统一并正确使用似乎更好。

有一则帖子说这是Eiya的工作备忘录,所以我想扩大它。最近很乱。 .. ^^;(2020/08/08)