天天看點

探尋世界:用Python擷取照片的地理定位資訊一、步驟:二、源代碼:三、代碼說明:四、報錯1:五、解決方法1:六、報錯2:七、解決方法2:八、效果如下所示:九、驗證效果如下:

目錄

步驟:

源代碼:

代碼說明:

報錯1:

解決方法1:

報錯2:

解決方法2:

效果如下所示:

驗證效果如下:

一、步驟:

要從 JPEG 圖像中擷取經緯度資訊,可以使用 Python 的 PIL(Python Imaging Library)庫。以下是一個示例代碼,用于從 JPEG 圖像中擷取經緯度資訊并列印出來:

二、源代碼:

from PIL import Image
from PIL.ExifTags import TAGS, GPSTAGS

def get_exif_data(image_path):
    """
    擷取 JPEG 圖像的 EXIF 資料
    """
    exif_data = {}
    with Image.open(image_path) as img:
        if hasattr(img, '_getexif'):
            # 擷取所有 EXIF 标簽
            for tag, value in img._getexif().items():
                if tag in TAGS:
                    exif_data[TAGS[tag]] = value
            # 擷取 GPSInfo 标簽
            if 'GPSInfo' in exif_data:
                # 解析 GPSInfo 标簽中的子标簽
                gps_data = {}
                for gps_tag in exif_data['GPSInfo'].keys():
                    tag_name = GPSTAGS.get(gps_tag, gps_tag)
                    gps_data[tag_name] = exif_data['GPSInfo'][gps_tag]
                exif_data['GPSInfo'] = gps_data
    return exif_data

def get_gps_info(exif_data):
    """
    從 EXIF 資料中提取經緯度資訊
    """
    gps_info = {}
    if 'GPSInfo' in exif_data:
        # 擷取經度
        lat = exif_data['GPSInfo']['GPSLatitude']
        lat_ref = exif_data['GPSInfo']['GPSLatitudeRef']
        # lat_degrees = lat[0][0] / float(lat[0][1])
        lat_degrees = lat[0].numerator / float(lat[0].denominator)
        # lat_minutes = lat[1][0] / float(lat[1][1])
        lat_minutes = lat[1].numerator / float(lat[1].denominator)        
        # lat_seconds = lat[2][0] / float(lat[2][1])
        lat_seconds = lat[2].numerator / float(lat[2].denominator)
        lat_direction = lat_ref
        gps_info['latitude'] = (lat_degrees + (lat_minutes / 60.0) + (lat_seconds / 3600.0)) * (-1 if lat_direction == 'S' else 1)
        

        # 擷取緯度
        lon = exif_data['GPSInfo']['GPSLongitude']
        lon_ref = exif_data['GPSInfo']['GPSLongitudeRef']
        # lon_degrees = lon[0][0] / float(lon[0][1])
        lon_degrees = lon[0].numerator / float(lon[0].denominator)
        # lon_minutes = lon[1][0] / float(lon[1][1])
        lon_minutes = lon[1].numerator / float(lon[1].denominator)
        # lon_seconds = lon[2][0] / float(lon[2][1])
        lon_seconds = lon[2].numerator / float(lon[2].denominator)
        lon_direction = lon_ref
        gps_info['longitude'] = (lon_degrees + (lon_minutes / 60.0) + (lon_seconds / 3600.0)) * (-1 if lon_direction == 'W' else 1)
    return gps_info

# 測試代碼
if __name__ == '__main__':
    image_path = r'D:\spiderdocs\FtpServer\IMG_20230302_134126.jpg'    
    # 修改為你自己的 JPEG 圖像路徑
    exif_data = get_exif_data(image_path)
    gps_info = get_gps_info(exif_data)
    print('經度:', gps_info['longitude'])
    print('緯度:', gps_info['latitude'])
           

三、代碼說明:

在上述代碼中,我們使用了

if hasattr(img, '_getexif'):

來檢查圖檔是否包含 EXIF 資料。如果包含,就将擷取到的 EXIF 資料儲存在

exif_data

變量中。然後再使用

if exif_data is None:

來檢查

exif_data

是否為

None

。如果是,就說明圖檔沒有 EXIF 資料,列印一條消息并傳回一個空字典。否則,将 EXIF 資料轉換為字典格式并傳回。 

四、報錯1:

Traceback (most recent call last):
  File "d:\spiderdocs\jpegexifgps.py", line 53, in <module>
    exif_data = get_exif_data(image_path)
  File "d:\spiderdocs\jpegexifgps.py", line 12, in get_exif_data
    for tag, value in img._getexif().items():
AttributeError: 'NoneType' object has no attribute 'items'
           

五、解決方法1:

出現這種情況的原因可能是檔案中沒有 EXIF 資料或者圖檔格式不支援 EXIF 資料。為了避免出現這種錯誤,您可以在調用 _getexif() 方法之前,先檢查一下是否存在 _getexif() 方法和傳回的 EXIF 資料是否為 None。如果是 None,則說明該圖檔沒有 EXIF 資料,需要相應地處理。
           
  1. 打開手機的相機應用,進入相機設定。
  2. 找到 “地理标記” 或者 “位置資訊” 這個選項,打開它。
  3. 確定允許相機應用通路位置資訊。在有些手機上,您需要在設定中打開相機應用的位置權限。
  4. 如果您希望在每次拍照時都儲存經緯度資訊,可以選擇“始終使用”或“啟用”選項。如果您隻想在需要時儲存位置資訊,可以選擇“詢問每次”選項。
  5. 拍攝照片時,手機會自動擷取目前位置的經緯度資訊,并将其儲存在照片的 EXIF 資料中。您可以使用一些工具或軟體來讀取照片的 EXIF 資料,并提取經緯度資訊。

請注意,啟用位置資訊會對手機的電池壽命産生一定影響。如果您不需要在拍照時儲存經緯度資訊,建議關閉位置資訊功能,以延長手機的電池壽命。

六、報錯2:

Traceback (most recent call last):
  File "d:\spiderdocs\jpegexifgps.py", line 57, in <module>
    gps_info = get_gps_info(exif_data)
  File "d:\spiderdocs\jpegexifgps.py", line 34, in get_gps_info
    lat_degrees = lat[0][0] / float(lat[0][1])
TypeError: 'IFDRational' object is not subscriptable
           

七、解決方法2:

這個錯誤是因為在讀取經緯度資訊時,使用了

IFDRational

類型的對象來進行下标操作,而

IFDRational

類型并不支援下标操作。

建議檢查代碼中讀取經緯度資訊的部分,并確定使用正确的資料類型進行操作。您可以嘗試使用

numerator

denominator

屬性來擷取

IFDRational

類型對象的值,例如:

類似地,您也可以使用

longitude[0].numerator

longitude[0].denominator

來擷取經度的度數。

lat_degrees = lat[0].numerator / float(lat[0].denominator)
           

八、效果如下所示:

探尋世界:用Python擷取照片的地理定位資訊一、步驟:二、源代碼:三、代碼說明:四、報錯1:五、解決方法1:六、報錯2:七、解決方法2:八、效果如下所示:九、驗證效果如下:

九、驗證效果如下:

1)打開:拾取坐标系統

2)輸入框中輸入:坐标(如:120.39987897666663,30.128810976666666)

注意:勾選“坐标反查”。

探尋世界:用Python擷取照片的地理定位資訊一、步驟:二、源代碼:三、代碼說明:四、報錯1:五、解決方法1:六、報錯2:七、解決方法2:八、效果如下所示:九、驗證效果如下: