前言
出去旅游,用iphone拍了非常多的照片,心想这些照片都有位置信息和拍摄时间信息,那能不能用python制作一个程序,输入所有照片,然后读取这些信息,最后输出一个xml路径文件,打开在googleEarth看。虽然最近逐步奉行“不讨论意义主义”,但我觉得此举的意义,首先是折腾python的乐趣,其次对于超长途旅行路线,能够结合更为宏观的视角来回顾本次旅行,譬如我发现原来我拍摄的地方,是甘肃和新疆的接壤,原来重庆在兰州的正下方偏东,原来我这次横跨了三个阶梯等等,能够带来许多乐趣。
序
csdn是程序员为主的博客平台,所以本文也会聚焦于这个程序,这个程序的功能在前言中已经有所概述,并且功能将会更丰富。定位是google Earth的小插件吧。能够输入照片,输出googleEarth使用的xml路径文件。
设计蓝图
主程序代码
主流程
参考文献:
How to extract GPS coordinates from Images in Python
How to extract GPS location from HEIC files?
一、获取单个HEIC文件的位置信息:
1.pillow库读取HEIC文件
2.获得照片拍摄的坐标,格式是Degrees, minutes, and seconds (DMS)
e.g.
(11.0, 53.0, 7.42199999)
3.将(DMS)格式坐标转化为 Decimal degrees (DD)格式。
e.g.
(43.46715666666389, 11.885394999997223)
4.坐标纠偏
5.难点:如何获得HEIC文件的拍摄时间?
根据如下这篇文章《python exif不能找到heic的“date taken”也就是拍摄时间,但是在windows资源管理器下却是可见的》
Python EXIF can’t find HEIC file date taken, but it’s visible in other tools
采用了如下方法:
import exifread
with open(filename, 'rb') as image:
exif = exifread.process_file(image)
但是报错,报错如下,并找到了解决方案也如下
exifread.process_file() throws “KeyError: ‘hdlr’” and “NoParser: hdlr Output is truncated.” for a HEIC image even though exifread can deal with HEIC
解决方案如原文:
This is just to share what I found on the net to fix this. Check HEIC processing error: hdlr on Apple Silicon #4.
Thus, you should downgrade to a version below 3.0.0:
也就是要将exifread降级到3以下,3以下最新的就是pip install exifread==2.3.2
然后不再报错文章来源:https://www.toymoban.com/news/detail-832866.html
最终程序:文章来源地址https://www.toymoban.com/news/detail-832866.html
import simplekml
import exifread
import os
from PIL import Image
from pillow_heif import register_heif_opener
register_heif_opener()
list2 = [('1', 51.500152, -0.126236), ('2', 1.500152, -50.126236)]
img_path = r'F:\trippicProject\pic\IMG_4563.HEIC'
HEICpath = r'F:\trippicProject\pic'
# 该函数用于将pillow获取的gps tag(DMS格式)转化为Decimal degrees (DD)(x,y)的格式
# you will get the coordinates in Degrees, minutes, and seconds (DMS). We will soon convert this format to Decimal degrees (DD) format.
def decimal_coords(coords, ref):
decimal_degrees = float(coords[0]) + float(coords[1]) / 60 + float(coords[2]) / 3600
if ref == 'S' or ref == 'W':
decimal_degrees = -decimal_degrees
return decimal_degrees
def get_heicGeoCoords(heicPath):
image = Image.open(heicPath)
image.verify()
exif = image.getexif().get_ifd(0x8825)
geo_tagging_info = {}
if not exif:
raise ValueError("No EXIF metadata found")
else:
gps_keys = ['GPSVersionID', 'GPSLatitudeRef', 'GPSLatitude', 'GPSLongitudeRef', 'GPSLongitude',
'GPSAltitudeRef', 'GPSAltitude', 'GPSTimeStamp', 'GPSSatellites', 'GPSStatus', 'GPSMeasureMode',
'GPSDOP', 'GPSSpeedRef', 'GPSSpeed', 'GPSTrackRef', 'GPSTrack', 'GPSImgDirectionRef',
'GPSImgDirection', 'GPSMapDatum', 'GPSDestLatitudeRef', 'GPSDestLatitude', 'GPSDestLongitudeRef',
'GPSDestLongitude', 'GPSDestBearingRef', 'GPSDestBearing', 'GPSDestDistanceRef', 'GPSDestDistance',
'GPSProcessingMethod', 'GPSAreaInformation', 'GPSDateStamp', 'GPSDifferential']
for k, v in exif.items():
try:
geo_tagging_info[gps_keys[k]] = v
except IndexError:
pass
coords = (decimal_coords(geo_tagging_info['GPSLatitude'], geo_tagging_info['GPSLatitudeRef']), decimal_coords(geo_tagging_info['GPSLongitude'], geo_tagging_info['GPSLongitudeRef']))
return coords
def get_heicTime(heicPath):
pic_data = exifread.process_file(open(heicPath, 'rb'))
time = pic_data['Image DateTime']
time_stamp = str(time)[2:4] + str(time)[5:7] + str(time)[8:10] + str(time)[11:13] + str(time)[14:16] + str(time)[17:19]
return time_stamp
if __name__ == '__main__':
imgs = os.listdir(r'F:\trippicProject\pic')
dateDatas = []
date2Details = {}
for imgName in imgs:
if imgName[-4:] == 'HEIC':
try:
img_path = HEICpath + '\\' + imgName
thisTime = get_heicTime(img_path)
thisCoords = get_heicGeoCoords(img_path)
dateDatas.append(int(thisTime))
date2Details[thisTime] = [thisCoords, imgName]
print("Done=>"+imgName)
except ValueError:
print("No EXIF metadata found=>"+imgName)
dateDatas.sort()
kml = simplekml.Kml()
lin = kml.newlinestring(name="trip")
lin.extrude = 1
lin.altitudemode = simplekml.AltitudeMode.clamptoground
lin.style.linestyle.width = 5
lin.style.linestyle.color = simplekml.Color.blue
for date in dateDatas:
coords = date2Details[str(date)][0]
pnt = kml.newpoint(description='test', coords=[(coords[1], coords[0])])
description = '<![CDATA[<img style="max-width:500px;" src="file:///F:/trippicProject/jpg/' + date2Details[str(date)][1][:-5] +'.jpg">]]>'
pnt.description = description
lin.coords.addcoordinates([(coords[1], coords[0])])
kml.save("test.kml")
到了这里,关于Python 获取 IOS/Iphone/Ipad等设备拍摄的HEIC图片的拍摄地址/坐标/位置以及python的googleEarth的xml文件绘制初步的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!