多线程写入gps元数据
import re
import os
import piexif
from PIL import Image
from concurrent.futures import ThreadPoolExecutor
def deg_to_dms_rational(deg_float):
"""
将十进制的经纬度转换为 EXIF 所需的 (度, 分, 秒) 的分数格式
"""
deg = abs(deg_float)
degrees = int(deg)
minutes = int((deg - degrees) * 60)
seconds = round((deg - degrees - minutes / 60) * 3600, 5)
return ((degrees, 1), (minutes, 1), (int(seconds * 1000), 1000))
def add_gps_exif(image_path, latitude, longitude):
"""
将给定的经纬度信息写入指定 JPEG 图片的 EXIF GPS 字段
"""
if not os.path.exists(image_path):
print(f"图片 {image_path} 不存在,跳过...")
return
lat_ref = "N" if latitude >= 0 else "S"
lon_ref = "E" if longitude >= 0 else "W"
lat_dms = deg_to_dms_rational(latitude)
lon_dms = deg_to_dms_rational(longitude)
gps_ifd = {
piexif.GPSIFD.GPSLatitudeRef: lat_ref,
piexif.GPSIFD.GPSLatitude: lat_dms,
piexif.GPSIFD.GPSLongitudeRef: lon_ref,
piexif.GPSIFD.GPSLongitude: lon_dms,
}
try:
exif_dict = piexif.load(image_path)
except Exception:
exif_dict = {"0th": {}, "Exif": {}, "GPS": {}, "1st": {}, "thumbnail": None}
exif_dict["GPS"] = gps_ifd
exif_bytes = piexif.dump(exif_dict)
img = Image.open(image_path)
img.save(image_path, "jpeg", exif=exif_bytes, quality=95) # 提高图片质量
print(f"已写入 {image_path}: latitude={latitude}, longitude={longitude}")
def parse_srt_file(srt_file_path):
"""
从srt文件中提取每组记录的latitude和longitude
"""
with open(srt_file_path, "r", encoding="utf-8") as f:
content = f.read()
pattern = re.compile(r"\[latitude:\s*(-?\d+\.\d+)\].*?\[longitude:\s*(-?\d+\.\d+)\]", re.DOTALL)
matches = pattern.findall(content)
return [(float(lat), float(lon)) for lat, lon in matches]
def process_image(idx, latitude, longitude, images_folder):
"""
处理单张图片的 GPS EXIF 信息写入
"""
image_filename = f"frame_{idx:06d}.jpg"
image_path = os.path.join(images_folder, image_filename)
add_gps_exif(image_path, latitude, longitude)
def main():
srt_file = "info.srt"
images_folder = "images"
gps_data_list = parse_srt_file(srt_file)
if not gps_data_list:
print("没有解析到GPS数据,请检查srt文件格式!")
return
with ThreadPoolExecutor() as executor:
futures = [executor.submit(process_image, idx, lat, lon, images_folder)
for idx, (lat, lon) in enumerate(gps_data_list, start=1)]
for future in futures:
future.result()
if __name__ == "__main__":
main()
import os
import piexif
from PIL import Image
from concurrent.futures import ThreadPoolExecutor
def deg_to_dms_rational(deg_float):
"""
将十进制的经纬度转换为 EXIF 所需的 (度, 分, 秒) 的分数格式
"""
deg = abs(deg_float)
degrees = int(deg)
minutes = int((deg - degrees) * 60)
seconds = round((deg - degrees - minutes / 60) * 3600, 5)
return ((degrees, 1), (minutes, 1), (int(seconds * 1000), 1000))
def add_gps_exif(image_path, latitude, longitude):
"""
将给定的经纬度信息写入指定 JPEG 图片的 EXIF GPS 字段
"""
if not os.path.exists(image_path):
print(f"图片 {image_path} 不存在,跳过...")
return
lat_ref = "N" if latitude >= 0 else "S"
lon_ref = "E" if longitude >= 0 else "W"
lat_dms = deg_to_dms_rational(latitude)
lon_dms = deg_to_dms_rational(longitude)
gps_ifd = {
piexif.GPSIFD.GPSLatitudeRef: lat_ref,
piexif.GPSIFD.GPSLatitude: lat_dms,
piexif.GPSIFD.GPSLongitudeRef: lon_ref,
piexif.GPSIFD.GPSLongitude: lon_dms,
}
try:
exif_dict = piexif.load(image_path)
except Exception:
exif_dict = {"0th": {}, "Exif": {}, "GPS": {}, "1st": {}, "thumbnail": None}
exif_dict["GPS"] = gps_ifd
exif_bytes = piexif.dump(exif_dict)
img = Image.open(image_path)
img.save(image_path, "jpeg", exif=exif_bytes, quality=95) # 提高图片质量
print(f"已写入 {image_path}: latitude={latitude}, longitude={longitude}")
def parse_srt_file(srt_file_path):
"""
从srt文件中提取每组记录的latitude和longitude
"""
with open(srt_file_path, "r", encoding="utf-8") as f:
content = f.read()
pattern = re.compile(r"\[latitude:\s*(-?\d+\.\d+)\].*?\[longitude:\s*(-?\d+\.\d+)\]", re.DOTALL)
matches = pattern.findall(content)
return [(float(lat), float(lon)) for lat, lon in matches]
def process_image(idx, latitude, longitude, images_folder):
"""
处理单张图片的 GPS EXIF 信息写入
"""
image_filename = f"frame_{idx:06d}.jpg"
image_path = os.path.join(images_folder, image_filename)
add_gps_exif(image_path, latitude, longitude)
def main():
srt_file = "info.srt"
images_folder = "images"
gps_data_list = parse_srt_file(srt_file)
if not gps_data_list:
print("没有解析到GPS数据,请检查srt文件格式!")
return
with ThreadPoolExecutor() as executor:
futures = [executor.submit(process_image, idx, lat, lon, images_folder)
for idx, (lat, lon) in enumerate(gps_data_list, start=1)]
for future in futures:
future.result()
if __name__ == "__main__":
main()
posted on 2025-02-03 09:50 shenhshihao 阅读(5) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」