내가 찍은 사진, 어디서 촬영했을까?Google 지도에서 확인하는 법

여행을 떠나며 우리는 수많은 사진을 찍습니다. 그런데 이 사진들 속에는 단순한 이미지 이상의 정보가 담겨 있다는 사실, 알고 계셨나요? 바로 EXIF 데이터입니다. 이 데이터를 활용하면 우리가 방문한 장소와 시간을 추적하고, 더 나아가 주변의 멋진 관광지나 맛집까지 추천받을 수 있습니다.

* 사전 지식 요건 : flask, python, Maps JavaScript API 에서 google map 에 접근 할 수 있는 api 를 발급 해야 합니다.

EXIF 데이터란 무엇인가요?

EXIF(Exchangeable Image File Format)는 디지털 사진 파일에 포함된 메타데이터로, 촬영 날짜, 시간, 카메라 설정, GPS 위치 정보 등 다양한 정보를 담고 있습니다. 특히 GPS 정보는 사진이 촬영된 정확한 위치를 알려주어 여행 경로를 재구성하는 데 큰 도움이 됩니다.

Camara EXIF
Camara EXIF

내가 사진을 촬영했던 장소는 어디였을까?

먼저, google maps api key 를 이용하여, google map 에 위치를 띄워보는 연습부터 해볼수 있습니다!

여기선 vscode 를 사용하여 개발했습니다.

1. 필수 라이브러리 설치

pip install flask pillow

2. Flask 서버 코드 작성

app.py 파일명으로 다음 코드를 작성 합니다.

import os
from flask import Flask, render_template, request, redirect, flash
from PIL import Image, ExifTags

app = Flask(__name__)
app.secret_key = 'your_secret_key'
UPLOAD_FOLDER = 'uploads'
if not os.path.exists(UPLOAD_FOLDER):
os.makedirs(UPLOAD_FOLDER)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

def get_exif_data(image):
"""이미지에서 EXIF 데이터를 추출하고, GPS 정보를 분리하여 반환"""
exif_data = {}
info = image._getexif()
if info is None:
return exif_data
for tag, value in info.items():
decoded = ExifTags.TAGS.get(tag, tag)
if decoded == "GPSInfo":
gps_data = {}
for t in value:
sub_decoded = ExifTags.GPSTAGS.get(t, t)
gps_data[sub_decoded] = value[t]
exif_data[decoded] = gps_data
else:
exif_data[decoded] = value
return exif_data

def get_decimal_from_dms(dms, ref):
"""GPS 좌표(DMS)를 십진수로 변환"""
degrees = dms[0][0] / dms[0][1]
minutes = dms[1][0] / dms[1][1]
seconds = dms[2][0] / dms[2][1]
decimal = degrees + minutes / 60 + seconds / 3600
if ref in ['S', 'W']:
decimal = -decimal
return decimal

def get_lat_lon(exif_data):
"""EXIF 데이터에서 위도와 경도를 추출"""
lat = None
lon = None
if "GPSInfo" in exif_data:
gps_info = exif_data["GPSInfo"]
if ("GPSLatitude" in gps_info and "GPSLatitudeRef" in gps_info and
"GPSLongitude" in gps_info and "GPSLongitudeRef" in gps_info):
lat = get_decimal_from_dms(gps_info["GPSLatitude"], gps_info["GPSLatitudeRef"])
lon = get_decimal_from_dms(gps_info["GPSLongitude"], gps_info["GPSLongitudeRef"])
return lat, lon

@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
if 'photo' not in request.files:
flash('파일이 없습니다')
return redirect(request.url)
file = request.files['photo']
if file.filename == '':
flash('선택된 파일이 없습니다')
return redirect(request.url)
if file:
filepath = os.path.join(app.config['UPLOAD_FOLDER'], file.filename)
file.save(filepath)
image = Image.open(filepath)
exif_data = get_exif_data(image)
lat, lon = get_lat_lon(exif_data)
if lat and lon:
# 추출한 좌표와 파일명을 map.html 템플릿으로 전달
return render_template('map.html', lat=lat, lon=lon, filename=file.filename)
else:
flash('GPS 정보가 없는 이미지입니다')
return redirect(request.url)
return render_template('upload.html')

if __name__ == '__main__':
app.run(debug=True)

3. HTML 템플릿 구성

Flask 템플릿 디렉터리(templates)에 두 개의 HTML 파일을 생성합니다.

3.1. 이미지 업로드 페이지 (templates/upload.html)

이미지를 업로드할 수 있는 간단한 폼을 구성합니다.

<pre>
&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;meta charset="utf-8"&gt;
  &lt;title&gt;이미지 업로드&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;h1&gt;이미지 업로드&lt;/h1&gt;
  {% with messages = get_flashed_messages() %}
  {% if messages %}
    &lt;ul&gt;
    {% for message in messages %}
      &lt;li&gt;{{ message }}&lt;/li&gt;
    {% endfor %}
    &lt;/ul&gt;
  {% endif %}
  {% endwith %}
  &lt;form method="post" enctype="multipart/form-data"&gt;
    &lt;input type="file" name="photo" accept="image/*"&gt;
    &lt;input type="submit" value="업로드"&gt;
  &lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>

4.2. 구글지도 표시 페이지 (templates/map.html)

<pre>
&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;meta charset="utf-8"&gt;
  &lt;title&gt;구글지도에 위치 표시&lt;/title&gt;
  &lt;style&gt;
    #map {
      height: 500px;
      width: 100%;
    }
  &lt;/style&gt;
  &lt;script src="https://maps.googleapis.com/maps/api/js?key=YOUR_GOOGLE_MAPS_API_KEY"&gt;&lt;/script&gt;
  &lt;script&gt;
    function initMap() {
      var location = {lat: {{ lat }}, lng: {{ lon }}};
      var map = new google.maps.Map(document.getElementById('map'), {
        zoom: 15,
        center: location
      });
      var marker = new google.maps.Marker({
        position: location,
        map: map,
        title: '사진 촬영 위치'
      });
    }
  &lt;/script&gt;
&lt;/head&gt;
&lt;body onload="initMap()"&gt;
  &lt;h1&gt;사진 촬영 위치&lt;/h1&gt;
  &lt;div id="map"&gt;&lt;/div&gt;
  &lt;p&gt;업로드한 파일: {{ filename }}&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>

업로드된 이미지에서 추출한 GPS 좌표를 활용해 구글 지도에 마커를 표시합니다. 반드시 아래 코드에서 YOUR_GOOGLE_MAPS_API_KEY 부분을 본인의 구글 API 키로 변경하세요.

5. 실행하기

1. app.py (오른쪽 상단 실행 버튼 을 누르고 서버 화면을 띄웁니다)

app.py
파이썬 실행

2.http://127.0.0.1:5000/ 주소로 접속 후 이미지를 업로드 하면 google map 화면에 다음과 같이 촬영 장소가 표시 됩니다.

localhost

3. 촬영 장소 를 상세히 확인을 할 수가 있습니다.

google maps

촬영한 장소를 파이썬 프로그램을 통해 간단히 지도에 표시하는 기능을 테스트 했습니다.

이제 다음 단계로, 해당 위치 주변의 맛집과 관광지 정보를 함께 표시하는 기능을 추가해보겠습니다. 사진의 EXIF 정보를 통해 주변의 흥미로운 장소들을 발견하여 새로운 여행 계획까지 가능 하구요!

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 항목은 *(으)로 표시합니다