PythonでJPEG画像にExifGPS情報を追加

GISアプリ

 

 

PythonでJPEG画像にExifGPS情報を追加するツール

ソースコードダウンロード

このページでは、Pythonを使用してJPEG画像にGPS情報を追加するツールについて解説します。このツールは、位置情報を後付けしたい写真や、撮影地情報が重要な場面で役立ちます。

ツールの使用方法

  1. 画像ファイルの選択: プログラムを起動し、画像ファイルを選択するダイアログが表示されます。
  2. 緯度・経度の入力: 緯度と経度の値を10進数形式で入力します。例として、東京タワーの座標は 35.6586, 139.7454 です。
  3. 画像処理の実行: 「画像処理」ボタンを押すと、指定された座標情報をEXIFデータとして画像に追加し、新しい画像ファイルとして保存します。

ソースコード

import os
from PIL import Image
from fractions import Fraction
import piexif
import tkinter as tk
from tkinter import filedialog

def to_deg(value, loc):
    '''10進数の座標を度、分、秒のタプルに変換する関数。
    
    value: 変換する座標値(緯度または経度)。
    loc: 緯度の場合は["S", "N"]、経度の場合は["W", "E"]を渡す。
    
    例: valueが35.6586でlocが["S", "N"]の場合、返り値は(35, 39, 30.96, "N")となる。
    '''
    if value < 0: loc_value = loc[0] # 負の場合は南緯または西経 elif value > 0:
        loc_value = loc[1]  # 正の場合は北緯または東経
    else:
        loc_value = ""  # 値が0の場合は空文字
    abs_value = abs(value)
    deg = int(abs_value)  # 度
    t1 = abs_value - deg
    min = int(t1 * 60)  # 分
    sec = round((t1 * 60 - min) * 60, 5)  # 秒(小数第5位まで)
    return (deg, min, sec, loc_value)

def change_to_rational(number):
    '''数値を分数に変換する関数。
    
    画像のEXIF情報に保存するため、数値を分数形式(numerator, denominator)に変換する。
    '''
    f = Fraction(str(number))
    return (f.numerator, f.denominator)

def set_gps_location(file_path, new_file_path, lat, lng):
    '''画像ファイルにGPS情報を設定し、新しいファイルとして保存する関数。
    
    file_path: 元の画像ファイルのパス。
    new_file_path: 新しく保存する画像ファイルのパス。
    lat: 緯度情報。
    lng: 経度情報。
    '''
    try:
        lat_deg = to_deg(lat, ["S", "N"])  # 緯度を度、分、秒形式に変換
        lng_deg = to_deg(lng, ["W", "E"])  # 経度を度、分、秒形式に変換

        # 画像からEXIFデータを読み込む
        exif_dict = piexif.load(file_path)
        # GPS情報を設定
        gps_ifd = {
            piexif.GPSIFD.GPSLatitudeRef: lat_deg[3],
            piexif.GPSIFD.GPSLatitude: tuple(map(change_to_rational, lat_deg[0:3])),
            piexif.GPSIFD.GPSLongitudeRef: lng_deg[3],
            piexif.GPSIFD.GPSLongitude: tuple(map(change_to_rational, lng_deg[0:3])),
            piexif.GPSIFD.GPSAltitudeRef: 0,  # 高度の基準(0=海面)
            piexif.GPSIFD.GPSAltitude: (100, 1),  # 高度を100mに固定
            piexif.GPSIFD.GPSDateStamp: u"2010:10:10",  # 固定の日付(デモ用)
            piexif.GPSIFD.GPSTimeStamp: ((10, 1), (10, 1), (10, 1))  # 固定の時間(デモ用)
        }
        exif_dict["GPS"] = gps_ifd
        exif_bytes = piexif.dump(exif_dict)

        # 画像を開いて、新しいEXIFデータで保存
        image = Image.open(file_path)
        image.save(new_file_path, exif=exif_bytes)
    except Exception as e:
        status_label.config(text=f"set_gps_locationでエラー: {str(e)}")

def process_image():
    '''ユーザーが入力した画像ファイルパスと座標情報を使って画像を処理する関数'''
    try:
        file_path = image_path_entry.get()
        lat, lng = map(float, coordinates_entry.get().split(','))  # 座標入力を取得し、数値に変換

        if os.path.exists(file_path):
            new_file_path = os.path.splitext(file_path)[0] + "_new.jpg"  # 新しいファイル名を作成
            set_gps_location(file_path, new_file_path, lat, lng)  # GPS情報を設定
            status_label.config(text="画像処理が完了しました。")  # 成功メッセージ
        else:
            status_label.config(text="無効な画像ファイルパスです。")  # 無効なパスの場合のエラーメッセージ
    except Exception as e:
        status_label.config(text=f"process_imageでエラー: {str(e)}")

def browse_image():
    '''画像ファイルを選択するためのファイルダイアログを表示する関数'''
    file_path = filedialog.askopenfilename(
        initialdir="/", 
        title="画像ファイルを選択", 
        filetypes=(("JPEGファイル", "*.jpg"), ("すべてのファイル", "*.*"))
    )
    image_path_entry.delete(0, tk.END)
    image_path_entry.insert(0, file_path)

window = tk.Tk()
window.title("画像 GPS 設定ツール")

image_path_label = tk.Label(window, text="画像ファイルパス:")
image_path_label.pack()
image_path_entry = tk.Entry(window, width=50)
image_path_entry.pack()
browse_button = tk.Button(window, text="参照", command=browse_image)
browse_button.pack()

coordinates_label = tk.Label(window, text="緯度,経度:")
coordinates_label.pack()
coordinates_entry = tk.Entry(window)
coordinates_entry.pack()

process_button = tk.Button(window, text="画像処理", command=process_image)
process_button.pack()

status_label = tk.Label(window, text="")
status_label.pack()

window.mainloop()

まとめ

このツールは、JPEG画像に対して正確な緯度・経度情報を付加することを可能にするPythonスクリプトです。写真の管理や記録を効率化することができ、旅行写真やプロフェッショナルな撮影現場でも活用可能です。

このプログラムを基に、独自のカスタマイズや機能追加も可能です。興味のある方は、ぜひ実装・利用してみてください。

#Pythonプログラミング #GPS情報追加 #EXIFデータ編集 #画像処理ツール #Pythonスクリプト #位置情報 #写真管理 #プログラミング初心者 #オープンソース #画像編集

コメント

タイトルとURLをコピーしました