유랑하는 나그네의 갱생 기록

だけど素敵な明日を願っている -HANABI, Mr.children-

Study/Python

python ExifTags와 argparse로 이미지 정보 출력

Madirony 2019. 8. 16. 04:38
728x90
import argparse
parser = argparse.ArgumentParser()
parser.parse_args()

 

argparse는 커맨드 라인에서 옵션을 주려구 가져왔어요.

 

parser.add_argument("-a", help="내용")

 

리눅스에서도 경험해봤겠지만

명령어 [옵션] 파일

형태로 명령을 내린다고 보면 됩니다.

옵션은 위 코드 한줄 추가해 주시고 작성해 주시구요.

 

--help를 치면 아래와 같이 옵션에 대한 설명이 나오도록 하고

옵션에 따라 원하는 정보를 출력하는 프로그램을 작성해봅시다.

 

먼저 이미지의 exif 정보를 불러와야겠죠.

 

from PIL import Image

def get_exif(filename):
    image = Image.open(filename)
    image.verify()
    return image._getexif()

exif = get_exif('image.jpg')
print(exif)

 

이미지 exif 정보를 불러오는 코드.

단순히 이것만 출력하면 뭐가 뭔지 도통 알 수가 없습니다.

아래 링크를 참고하면 대충 뭔지는 알 수 있는데 하나하나 대조해보기도 좀 거시기하구요.

https://www.exiv2.org/tags.html

 

 

306은 촬영 일을 뜻 합니다.

 

사이트를 들어가면 대충 숫자가 뭐를 뜻하는지 알려줘요.

근데 이걸 알아서 번역해주는 코드가 있답니다.

 

from PIL.ExifTags import TAGS

def get_labeled_exif(exif):
    labeled = {}
    for (key, val) in exif.items():
        labeled[TAGS.get(key)] = val

    return labeled

exif = get_exif('image.jpg')
labeled = get_labeled_exif(exif)
print(labeled)

 

이런 식으로 작성하면 사용자가 읽을 수 있는 데이터로 변형시켜 줍니다.

 

 

GPSInfo = {1: 'N', 2: ((36, 1), (7, 1), (5263, 100)), 3: 'W', 4: ((115, 1), (8, 1), (5789, 100)), 5: b'\x00', 6: (241175, 391), 7: ((19, 1), (8, 1), (40, 1)), 12: 'K', 13: (0, 1), 16: 'T', 17: (1017664, 4813), 23: 'T', 24: (1017664, 4813), 29: '2019:01:11', 31: (65, 1)}
Make = Apple
Model = iPhone 8
Software = 12.1.2
ShutterSpeedValue = (223247, 48685)
DateTimeOriginal = 2019:01:11 11:08:47
FocalLength = (399, 100)
ColorSpace = 65535
ExifImageWidth = 4032

뭐 대충 이런 식으로 변형됩니다.

전보다 훨씬 낫죠.

 

GPS의 위도 경도가 일반적인 위도 경도가 아니라 따로 코드를 작성해서 변형을 시켜야 하는데

나중에 적용시켜 볼 거예요. GPS는 GPSTAGS로도 불러와집니다.

from PIL.ExifTags import GPSTAGS

def get_geotagging(exif):
    if not exif:
        raise ValueError("No EXIF metadata found")

    geotagging = {}
    for (idx, tag) in TAGS.items():
        if tag == 'GPSInfo':
            if idx not in exif:
                raise ValueError("No EXIF geotagging found")

            for (key, val) in GPSTAGS.items():
                if key in exif[idx]:
                    geotagging[val] = exif[idx][key]

    return geotagging

exif = get_exif('image.jpg')
geotags = get_geotagging(exif)
print(geotags)


-----------------------------------------------------------------------------------

{
    'GPSLatitudeRef': 'N',
    'GPSLatitude': ((36, 1), (7, 1), (5263, 100)),
    'GPSLongitudeRef': 'W',
    'GPSLongitude': ((115, 1), (8, 1), (5789, 100)),
    'GPSTimeStamp': ((19, 1), (8, 1), (40, 1)),
    ...
}

------------------------------------------------------------------------------------

def get_decimal_from_dms(dms, ref):

    degrees = dms[0][0] / dms[0][1]
    minutes = dms[1][0] / dms[1][1] / 60.0
    seconds = dms[2][0] / dms[2][1] / 3600.0

    if ref in ['S', 'W']:
        degrees = -degrees
        minutes = -minutes
        seconds = -seconds

    return round(degrees + minutes + seconds, 5)

def get_coordinates(geotags):
    lat = get_decimal_from_dms(geotags['GPSLatitude'], geotags['GPSLatitudeRef'])

    lon = get_decimal_from_dms(geotags['GPSLongitude'], geotags['GPSLongitudeRef'])

    return (lat,lon)


exif = get_exif('image.jpg')
geotags = get_geotagging(exif)
print(get_coordinates(geotags))

 

GUI로 만들어서 EXE 파일로 실행되게끔 하고 싶었는데

아직은 갈 길이 머네요....

 

 

sys 모듈을 썼으면 좀 더 짧게 만들 수 있었을 듯싶네요.

 

from PIL import Image
from PIL.ExifTags import TAGS
import argparse

parser = argparse.ArgumentParser()
parser.add_argument("-a", help="모든 exif 정보 출력")
parser.add_argument("-d", help="촬영일 출력")
parser.add_argument("-i", help="이미지 크기")
args = parser.parse_args()

if bool(args.a) == True:
	with Image.open(args.a) as img:
		try:
			info = img._getexif()
			for tag,value in info.items():
				decoded = TAGS.get(tag,tag)
				print(decoded,value)
		except:
			print("exif 정보가 없습니다.")

if bool(args.d) == True:
	with Image.open(args.d) as img:
		try:
			info = img._getexif()
			for tag,value in info.items():
				decoded = TAGS.get(tag,tag)
				if decoded == "DateTime":
					print("촬영일 : ",value)
		except:
			print("exif 정보가 없습니다.")

if bool(args.i) == True:
	with Image.open(args.i) as img:
		try:
			info = img._getexif()
			for tag,value in info.items():
				decoded = TAGS.get(tag,tag)
				if decoded == "ImageWidth":
					print("너비 : ",value)
				elif decoded == "ImageLength":
					print("높이 : ",value)
		except:
			print("exif 정보가 없습니다.")

커맨드 라인에서 가져온 옵션 뒤에 입력한 내용이 있는지 없는지에 따라 

True False 값으로 간주할 수 있습니다.

 

 

a옵션

 

d옵션, i옵션

 

간단한 exif 정보를 출력하는 코드를 짜 봤는데요....

좀 불만족스럽습니다.

실행 파일로는 못 만들더라도 gps로 위치 정도는 크롤링해서 출력해봐야겠습니다......

728x90