摄影爱好者必备:用Python和Pillow库批量管理照片EXIF,轻松整理旅行相册

张开发
2026/4/15 6:11:09 15 分钟阅读

分享文章

摄影爱好者必备:用Python和Pillow库批量管理照片EXIF,轻松整理旅行相册
摄影爱好者必备用Python和Pillow库批量管理照片EXIF轻松整理旅行相册每次旅行归来面对手机和相机里上千张杂乱无章的照片你是否也感到无从下手那些珍贵的回忆被埋没在混乱的文件夹中想要找到特定时间或地点拍摄的照片简直如同大海捞针。其实每张照片都自带一个数字身份证——EXIF信息它记录了拍摄时间、设备参数甚至地理位置等宝贵数据。掌握这些信息你就能像专业摄影师一样高效管理自己的照片库。Python的Pillow库为我们提供了强大的EXIF处理能力配合简单的脚本编写可以实现批量读取、修改和利用EXIF信息进行自动化整理。不同于简单的信息查看我们将重点探讨如何将这些技术转化为实际的工作流让你的照片管理从手动劳动升级为智能操作。无论是统一添加版权信息还是按拍摄时间自动归档亦或是保护隐私选择性删除敏感数据这些操作都可以通过代码批量完成。1. EXIF信息你的照片隐藏的宝藏EXIF可交换图像文件格式是数码照片中嵌入的元数据它就像照片的黑匣子忠实记录了拍摄时的各种参数。对于摄影爱好者来说这些数据不仅是技术分析的依据更是组织照片的关键线索。典型的EXIF信息包括基础信息拍摄时间、最后修改时间设备参数相机厂商、型号、镜头焦距拍摄设置光圈值、快门速度、ISO感光度位置数据GPS坐标如果启用版权信息作者、版权声明理解这些字段的含义是有效管理照片的第一步。例如DateTimeOriginal记录的是拍摄的原始时间而DateTimeDigitized则表示照片被数字化的时间。对于旅行照片GPSInfo中的经纬度数据可以帮助你在地图上重现整个旅程。from PIL import Image from PIL.ExifTags import TAGS def print_exif(image_path): img Image.open(image_path) exif_data img._getexif() if exif_data: for tag_id, value in exif_data.items(): tag_name TAGS.get(tag_id, tag_id) print(f{tag_name:25}: {value}) else: print(没有找到EXIF信息) # 示例使用 print_exif(travel_photo.jpg)这段基础代码可以打印出照片中的所有EXIF信息。运行后你会看到类似这样的输出ExposureTime : 0.0025 FNumber : 2.8 ISOSpeedRatings : 400 DateTimeOriginal : 2023:07:15 08:30:22 DateTimeDigitized : 2023:07:15 08:30:22 ... GPSInfo : {1: N, 2: ((38, 1), (53, 1), (246, 100)), 3: E, ...}提示不同设备生成的EXIF标签可能有所差异建议先打印全部信息了解你的照片包含哪些具体字段。2. 批量处理高效管理照片库的核心技能单张照片的EXIF操作意义有限真正的效率提升来自于批量处理能力。想象一下你可以一次性为整个旅行相册的所有照片添加统一的版权信息或者按拍摄日期自动重命名数百张照片这些操作通过Python脚本都能轻松实现。2.1 批量读取与修改EXIF首先我们需要构建一个能够遍历文件夹中所有照片的脚本框架import os from PIL import Image from PIL.ExifTags import TAGS, GPSTAGS def batch_process_exif(folder_path, process_func): for root, _, files in os.walk(folder_path): for file in files: if file.lower().endswith((.jpg, .jpeg, .png)): try: img_path os.path.join(root, file) with Image.open(img_path) as img: exif_data img._getexif() or {} new_exif process_func(exif_data) if new_exif is not None: save_with_exif(img, img_path, new_exif) except Exception as e: print(f处理 {file} 时出错: {e}) def save_with_exif(img, path, exif_data): # 保存图片并保留EXIF数据 img.save(path, exifexif_data)这个框架可以接受一个处理函数应用到文件夹中的每张照片上。下面是一些实用的处理函数示例添加版权信息def add_copyright(exif_data): # 36867是DateTimeOriginal的标签ID exif_data[36867] 2023:12:01 00:00:00 # 修改拍摄时间 exif_data[33432] © Your Name # 版权信息 return exif_data移除GPS位置信息def remove_gps_data(exif_data): # 删除所有GPS相关标签 gps_tags [tag for tag in exif_data if TAGS.get(tag) and TAGS[tag].startswith(GPS)] for tag in gps_tags: del exif_data[tag] return exif_data2.2 基于EXIF的照片重命名照片的默认命名如DSC_1234.jpg往往没有意义。利用EXIF中的拍摄时间我们可以批量重命名照片import os from datetime import datetime def rename_by_datetime(folder_path): for root, _, files in os.walk(folder_path): for file in files: if file.lower().endswith((.jpg, .jpeg)): img_path os.path.join(root, file) try: with Image.open(img_path) as img: exif img._getexif() if exif and 36867 in exif: # 36867是DateTimeOriginal dt datetime.strptime(exif[36867], %Y:%m:%d %H:%M:%S) new_name dt.strftime(IMG_%Y%m%d_%H%M%S) os.path.splitext(file)[1] os.rename(img_path, os.path.join(root, new_name)) except Exception as e: print(f重命名 {file} 时出错: {e})这个脚本会将照片重命名为类似IMG_20230715_083022.jpg的格式让你一眼就能看出拍摄时间。3. 智能归档让照片自动找到归属有了批量处理能力我们可以更进一步利用EXIF信息实现照片的智能分类和归档。以下是几种常见的归档策略3.1 按日期归档最基本的归档方式是按拍摄日期组织照片旅行相册/ ├── 2023-07-15/ │ ├── IMG_20230715_083022.jpg │ └── IMG_20230715_091545.jpg ├── 2023-07-16/ │ ├── IMG_20230716_073210.jpg │ └── IMG_20230716_142315.jpg实现代码import shutil from datetime import datetime def organize_by_date(source_folder, target_folder): if not os.path.exists(target_folder): os.makedirs(target_folder) for root, _, files in os.walk(source_folder): for file in files: if file.lower().endswith((.jpg, .jpeg)): img_path os.path.join(root, file) try: with Image.open(img_path) as img: exif img._getexif() if exif and 36867 in exif: dt datetime.strptime(exif[36867], %Y:%m:%d %H:%M:%S) date_folder os.path.join(target_folder, dt.strftime(%Y-%m-%d)) if not os.path.exists(date_folder): os.makedirs(date_folder) shutil.copy2(img_path, os.path.join(date_folder, file)) except Exception as e: print(f归档 {file} 时出错: {e})3.2 按地点归档需GPS信息如果照片包含GPS数据我们可以按拍摄地点分类import reverse_geocoder as rg def get_location_name(lat, lon): results rg.search((lat, lon)) if results: return f{results[0][name]}, {results[0][admin1]} return Unknown Location def organize_by_location(source_folder, target_folder): for root, _, files in os.walk(source_folder): for file in files: if file.lower().endswith((.jpg, .jpeg)): img_path os.path.join(root, file) try: with Image.open(img_path) as img: exif img._getexif() if exif and 34853 in exif: # GPSInfo标签 gps_info exif[34853] lat convert_to_degrees(gps_info[2]) if gps_info[1] S: lat -lat lon convert_to_degrees(gps_info[4]) if gps_info[3] W: lon -lon location get_location_name(lat, lon) location_folder os.path.join(target_folder, location) if not os.path.exists(location_folder): os.makedirs(location_folder) shutil.copy2(img_path, os.path.join(location_folder, file)) except Exception as e: print(f归档 {file} 时出错: {e})注意使用GPS数据前请确保你有权处理这些可能涉及隐私的信息。分享照片前考虑是否需要删除位置数据。4. 高级技巧EXIF与照片工作流的深度整合掌握了基础操作后我们可以将EXIF管理融入整个照片处理流程实现更智能的工作流。4.1 自动生成旅行轨迹地图结合GPS数据我们可以将照片的拍摄地点绘制在地图上直观展示旅行路线import folium from glob import glob def create_travel_map(photo_folder, output_file): photo_paths glob(os.path.join(photo_folder, **/*.jpg), recursiveTrue) locations [] for path in photo_paths: try: with Image.open(path) as img: exif img._getexif() if exif and 34853 in exif: gps_info exif[34853] lat convert_to_degrees(gps_info[2]) if gps_info[1] S: lat -lat lon convert_to_degrees(gps_info[4]) if gps_info[3] W: lon -lon locations.append((lat, lon)) except: continue if locations: m folium.Map(locationlocations[0], zoom_start10) folium.PolyLine(locations, colorblue, weight2.5, opacity1).add_to(m) for i, loc in enumerate(locations): folium.Marker(loc, popupf照片点 {i1}).add_to(m) m.save(output_file)4.2 基于EXIF的照片筛选你可以根据特定条件筛选照片例如找出所有用特定相机拍摄或特定参数设置的照片def find_photos_by_camera(folder, makeNone, modelNone): matching_photos [] for root, _, files in os.walk(folder): for file in files: if file.lower().endswith((.jpg, .jpeg)): img_path os.path.join(root, file) try: with Image.open(img_path) as img: exif img._getexif() if exif: img_make exif.get(271, ).strip() img_model exif.get(272, ).strip() if (not make or img_make.lower() make.lower()) and \ (not model or img_model.lower() model.lower()): matching_photos.append(img_path) except: continue return matching_photos4.3 EXIF与云服务集成将你的脚本与云存储服务如Dropbox、Google Drive结合可以实现自动备份和整理import dropbox from dropbox.files import WriteMode def upload_to_dropbox(local_path, dropbox_path, token): dbx dropbox.Dropbox(token) with open(local_path, rb) as f: dbx.files_upload(f.read(), dropbox_path, modeWriteMode(overwrite))结合之前的归档函数你可以创建一个完整的自动化流程本地整理 → 添加元数据 → 上传到云端特定文件夹。5. 实战案例构建完整的旅行照片处理流程让我们将这些技术整合成一个完整的旅行照片处理流程。假设你刚从一次旅行回来手机和相机里有上千张照片存储在一个名为2023_Japan_Trip的文件夹中。5.1 第一步统一整理原始照片# 将所有照片复制到一个统一目录并按日期分类 source_folders [/path/to/camera, /path/to/phone] target_folder /path/to/2023_Japan_Trip_Organized for folder in source_folders: organize_by_date(folder, target_folder)5.2 第二步批量处理EXIF信息# 为所有照片添加版权信息 batch_process_exif(target_folder, add_copyright) # 移除GPS信息如果要在社交媒体分享 batch_process_exif(target_folder, remove_gps_data)5.3 第三步生成旅行可视化# 创建旅行路线图 create_travel_map(target_folder, japan_trip_map.html) # 按城市创建相册 organize_by_location(target_folder, /path/to/Japan_Trip_By_City)5.4 第四步备份到云端# 上传整理好的照片到Dropbox for root, _, files in os.walk(target_folder): for file in files: if file.lower().endswith((.jpg, .jpeg, .png)): local_path os.path.join(root, file) dropbox_path os.path.join(/Japan_Trip, os.path.relpath(local_path, target_folder)) upload_to_dropbox(local_path, dropbox_path, your_dropbox_token)这个完整流程将原本需要数小时的手动工作压缩为几分钟的自动化处理而且更加准确可靠。你可以在每次旅行后运行类似的脚本保持照片库的整洁有序。

更多文章