使用PIL、exif库按经纬度将地图拼接照片分四象限存储的实现问题
实现批量照片按经纬度象限分类的Python方案
错误原因说明
你之前的报错是因为直接遍历字符串类型的源路径
source_path,循环变量i是路径字符串拆分出的单个字符,自然没有gps_longitude属性。正确实现需要先遍历目标目录下的所有图片文件,读取有效GPS信息后再做后续计算。
前置依赖安装
pip install exif pillow
完整实现代码
import os import shutil from exif import Image # 工具函数:将EXIF的度分秒格式经纬度转换为十进制数值 def dms_to_decimal(coords, ref): decimal = coords[0] + coords[1] / 60 + coords[2] / 3600 # 西经、南纬为负值 if ref in ['W', 'S']: decimal = -decimal return decimal # 配置参数 source_dir = r"C:\Users\q\Pictures\Test" # 支持的图片格式 img_extensions = ('.jpg', '.jpeg', '.png', '.tiff') # 四个象限文件夹名,可自行修改 quadrant_dirs = { 'q1': '象限1_东北', 'q2': '象限2_西北', 'q3': '象限3_西南', 'q4': '象限4_东南' } # ---------------------- 第一阶段:遍历所有图片收集经纬度,计算象限中点 ---------------------- all_lon = [] all_lat = [] img_path_list = [] # 遍历源目录下所有文件 for root, _, files in os.walk(source_dir): for file in files: if file.lower().endswith(img_extensions): img_path = os.path.join(root, file) try: with open(img_path, 'rb') as f: img = Image(f) # 检查是否包含GPS信息 if not img.has_exif or not hasattr(img, 'gps_longitude'): print(f"跳过无GPS信息的文件:{img_path}") continue # 转换为十进制经纬度 lon = dms_to_decimal(img.gps_longitude, img.gps_longitude_ref) lat = dms_to_decimal(img.gps_latitude, img.gps_latitude_ref) all_lon.append(lon) all_lat.append(lat) img_path_list.append((img_path, lon, lat)) except Exception as e: print(f"读取文件{img_path}失败:{str(e)}") if not all_lon or not all_lat: raise Exception("未找到任何包含有效GPS信息的图片") # 计算象限划分中点 mid_lon = (max(all_lon) + min(all_lon)) / 2 mid_lat = (max(all_lat) + min(all_lat)) / 2 print(f"象限划分中点:经度{mid_lon:.6f},纬度{mid_lat:.6f}") # ---------------------- 第二阶段:按象限分类存储图片 ---------------------- # 创建象限文件夹 for dir_name in quadrant_dirs.values(): dir_path = os.path.join(source_dir, dir_name) os.makedirs(dir_path, exist_ok=True) # 逐个处理图片 for img_path, lon, lat in img_path_list: # 判断所属象限 if lat >= mid_lat and lon >= mid_lon: target_dir = quadrant_dirs['q1'] elif lat >= mid_lat and lon < mid_lon: target_dir = quadrant_dirs['q2'] elif lat < mid_lat and lon < mid_lon: target_dir = quadrant_dirs['q3'] else: target_dir = quadrant_dirs['q4'] # 复制文件到目标文件夹,如需移动文件可替换为shutil.move shutil.copy2(img_path, os.path.join(source_dir, target_dir, os.path.basename(img_path))) print(f"已处理文件{os.path.basename(img_path)},存入{target_dir}")
注意事项
- 默认是复制原文件到对应象限文件夹,不会修改原文件,确认分类正确后可将
shutil.copy2替换为shutil.move直接移动文件 - 代码会自动跳过没有EXIF GPS信息的图片,运行时会输出对应提示
- 可自行修改
quadrant_dirs的value值调整四个象限的文件夹命名
内容的提问来源于stack exchange,提问作者GuysthisisQais
相关产品推荐
相关产品推荐

