前阵子帮一位做户外记录的朋友整理素材,几百张照片混在一个文件夹里,一半是相机拍的,一半是手机拍的。他让我按拍摄地点归档,我随手看了下文件属性,手机拍的每张都带着经纬度,相机拍的全是空白。他当时问的那句话特别典型:照片上的经纬度、地址这些到底是怎么弄上去的?相机本身没有 GPS,还能不能事后把坐标写进去?
答案当然是能,而且路子不止一条。这篇就按我自己的实操顺序,把照片里的 EXIF、GPS 标签结构、写入工具、批量脚本和踩过的坑一次讲透。不管你是用手机随手拍、用无反单反认真拍,还是手里攒了几百 GB 老照片想补坐标做归档,都能从里面找到可以直接抄作业的方案。核心只有一件事:把经纬度按 EXIF 能读懂的格式,准确塞进照片的 GPS 段里,同时别把原图搞坏。
1. 照片里的经纬度到底存在哪,先把这件事说透
很多人以为"位置信息"是图片内容的一部分,其实它跟画面像素一点关系都没有,纯粹是文件头里的一段结构化数据。你右键看属性能看到它,是因为系统读了这段数据;某些软件看不到,是因为它压根没去读,或者读的是另一个位置。搞清楚数据存在哪、长什么格式,后面所有写入操作才有依据,否则就是照着命令瞎敲,出错也不知道错在哪。
1.1 EXIF 的 GPS 段是一套独立的标签体系
一张 JPEG 的元数据大致分几块:0th IFD 放基础信息(相机型号、分辨率、拍摄时间),Exif IFD 放拍摄参数(光圈、快门、ISO、镜头),GPS IFD 专门放位置,1st IFD 放缩略图。GPS 段是独立的一块,跟拍摄参数互不干扰,所以你完全可以只写 GPS 而不动其他任何东西,这也是事后补坐标最安全的做法。
GPS 段里最核心的几个标签,我用表格列一下,这几个是你必须认识的最小集合:
| 标签名 | 类型 | 说明 | 常见错误 |
|---|---|---|---|
| GPSVersionID | BYTE×4 | 版本号,一般写 2.3.0.0 | 缺失导致老软件不认 |
| GPSLatitudeRef | ASCII×2 | 纬度方向,N 或 S | 写成小写或数值 |
| GPSLatitude | RATIONAL×3 | 纬度,度/分/秒三个分数 | 直接塞十进制小数 |
| GPSLongitudeRef | ASCII×2 | 经度方向,E 或 W | 与纬度 Ref 写反 |
| GPSLongitude | RATIONAL×3 | 经度,度/分/秒三个分数 | 同上 |
| GPSAltitudeRef | BYTE | 0 表示海平面以上,1 表示以下 | 漏写导致高度为正负不明 |
| GPSAltitude | RATIONAL | 海拔,单位米 | 单位写成英尺 |
| GPSMapDatum | ASCII | 坐标系,通常写 WGS-84 | 写成 CGCS2000 等本地坐标系 |
| GPSDateStamp / GPSTimeStamp | ASCII / RATIONAL×3 | UTC 日期与时间 | 写成本地时间导致偏差 |
这里有个坑必须提前说:GPSLatitude 和 GPSLongitude 不是十进制度数,而是三个有理数组成的"度、分、秒"。比如纬度 30.1234 度,实际要写成 (30/1, 7/1, 2424/100),也就是 30 度 7 分 24.24 秒。如果你直接把 30.1234 塞进去,绝大多数写入工具会报类型错误;就算某些工具"帮你转换"了,也可能把小数部分当成分来处理,出来的坐标能偏出去几十公里。
1.2 相机为什么不写坐标,不是做不到而是不值得
经常有人问,现在手机都能定位,相机加个 GPS 模块能有多难。技术上确实不难,难的是成本、功耗和体验的平衡。GPS 模块冷启动搜星要几十秒,开机就耗电,金属机身还会屏蔽信号,室内基本无效。一台相机卖几千上万,用户对续航极其敏感,厂商算过账,觉得这笔投入不划算。
所以你会发现一个现象:入门机型直接砍掉定位功能,中高端机型改用"配套手机 App 通过蓝牙把位置传给相机"的方案,拍摄时实时写入。这个方案在室内、在信号差的地方依然会失效,而且连接稳定性一言难尽,经常是拍了一整天回来发现后半段全没定位。这也是为什么"事后补坐标"这个需求长期存在,而且短期不会消失。
还有一层原因是隐私。位置信息属于敏感数据,厂商在默认行为上越来越保守,能不写就不写。近两年新系统对相册、定位权限收得更紧,很多 App 想读照片位置都得单独授权,这个趋势很明显。
1.3 补坐标的三条技术路线,先选对再动手
我把实际能用的方案归成三类,你可以对着自己的场景挑:
- 单点写入:知道每张照片大概在哪个位置,在地图上打点,直接把坐标写进文件。适合照片量不大、地点明确的情况,比如给一批产品图标注拍摄门店。
- 轨迹匹配:用一个能记录轨迹的设备(手机 App、手持记录仪)全程记下路径,事后按拍摄时间把每张照片匹配到轨迹上的对应点。适合外拍、徒步、自驾这类移动拍摄,几百上千张也能一次搞定。
- 标签借用:手机在同一位置拍一张,把那张照片的 GPS 标签整段复制到相机照片上。适合打卡式的定点拍摄,操作最省事,但要小心别把手机的其他元数据一起带过去。
三条路线的工具链和精度差别很大。单点写入靠手工,精度取决于你打点的仔细程度;轨迹匹配精度取决于时间对齐做得好不好,做得好可以到几米;标签借用精度就是手机当时的定位精度,通常五到十米,城市高楼间可能更差。
2. 动手之前,先把坐标来源和时间基准理清楚
我见过太多人卡在这一步:命令敲得挺熟,写完了发现位置全错。问题基本都不是出在写入工具上,而是出在数据源。坐标本身不准,或者时间对不上,后面再精细的操作都是白费。这一节讲的就是怎么把"原料"准备好。
2.1 坐标从哪来:三种可靠来源
最省事的来源是手机轨迹记录。市面上有大量能导出 GPX 格式的运动记录工具,走一段路、开一段车,导出文件里就是一串带时间戳的坐标点。GPX 本质是 XML,结构很朴素,核心就是<trkpt lat="..." lon="...">里面套一个<time>,格式是 UTC 的 ISO 8601。你完全可以自己打开看一眼,确认里面确实有点,而不是空文件。
第二种是手持记录仪或者带定位功能的运动相机,精度通常比手机好,尤其是在山谷、林区这类手机信号弱的地方。这类设备导出的格式五花八门,但基本都能转成 GPX,转不了就手工整理成 CSV。
第三种是地图上手动取点。打开任意地图工具,找到位置,读出经纬度,抄下来。这种方式精度取决于地图底图的精度和你点得准不准,城市里点错一栋楼很常见,适合对精度要求不高的场景。我一般建议至少取到小数点后六位,因为十进制度六位小数大约对应十一厘米,再少就没意义了。
2.2 时间对齐才是精度的命门
轨迹匹配的原理说起来简单:照片的拍摄时间去轨迹里找最接近的点,取那个点的坐标。问题在于,相机记录的拍摄时间和你以为的时间,经常对不上。
相机时钟是会漂的。出厂设置可能差几分钟,用久了电池拆装、长时间不用,漂几小时都有可能。我自己遇到过一次,相机时间比实际慢了将近四十分钟,一批两百多张照片全被匹配到了轨迹起点附近,出来的坐标挤成一团,白忙活一下午。
更麻烦的是时区。GPX 里的时间是 UTC,而相机 EXIF 里的DateTimeOriginal通常是本地时间,而且不带时区信息。也就是说,文件里只写了"14:30:00",没写这是哪个时区的 14:30。如果你不处理,匹配结果会整体偏移八小时,照片全跑到轨迹的另一头去。
实操上我有两个习惯。第一,每次外出拍摄前,用手机拍一张相机屏幕,屏幕上显示着相机的当前日期时间,这张照片同时带有手机的准确时间和准确位置,事后拿它当"对时基准",误差一目了然。第二,导入时统一用-geosync参数做整体偏移校正,而不是一张张去改。这个参数后面会给具体用法。
注意:不要指望相机的自动对时功能。很多机型的"通过手机同步时间"只在连接 App 的那一刻生效,之后继续漂。养成开拍前手动核对一次时间的习惯,能省掉后面大量返工。
3. 图形化工具方案:不碰命令行也能搞定
不是所有人都愿意敲命令,所以先把图形化的路子讲清楚。这类方案的共同优点是上手快,缺点是批量处理能力弱、可控性差,遇到稍微复杂一点的需求就抓瞎。
3.1 相机配套 App 的蓝牙同步,能用但别全信
主流品牌的配套手机 App 基本都有"位置信息同步"功能,通过蓝牙连接相机,拍摄时把手机的位置写进照片。设置路径大同小异:相机菜单里打开蓝牙和位置同步,手机 App 里授权定位权限(注意要选"始终允许",选"仅使用期间"的话,App 切到后台就断了),配对成功后相机会显示一个定位图标。
这套方案的体验说实话一般。连接建立慢,走进室内或者手机锁屏久了容易断,断了之后相机不会提示,你以为在记录其实早就停了。我的建议是把它当成"锦上添花",重要拍摄还是老老实实用轨迹记录兜底。另外,同步写入的位置精度就是手机定位精度,而且很多机型只在拍摄瞬间取一次位置,移动拍摄时会有明显滞后。
3.2 桌面端地图打点工具,适合定点批量标注
电脑上有一类工具,界面是左边一张地图、右边一个文件列表,你把照片拖进去,在地图上点一下,坐标就写进去了。这类工具的优势是直观,适合给门店照、样板间、房产图这类位置固定的照片批量标注——同一批照片在同一个位置,点一次就能全部应用。
用这类工具时要注意两件事。一是确认它写的是 EXIF 的 GPS 段,而不是只写进自己的数据库。有些工具看起来"标注成功",其实只是在自己的工程文件里记了一笔,导出的图片本身没有坐标。验证方法很简单,用任意一个能读 EXIF 的查看器打开导出的图,看 GPS 段是不是真有值。二是注意它对原图的处理方式,有些工具会重新编码,JPEG 质量掉一截,几百张图批量处理下来画质损失是肉眼可见的。
3.3 手机端直接改图,方便但风险最高
手机上确实有能直接给照片写坐标的 App,操作路径通常是选图、在地图上选点、保存。方便是真方便,但我一般不建议在原始素材上这么干,原因有两个。
第一是重压缩。手机端处理图片的 App 很多会走系统的图像处理管线,保存时重新编码,EXIF 里的拍摄参数可能被清空,画质也会掉。第二是权限问题,近两年新系统对"修改相册文件"的授权越来越严,App 只能拿到一个副本,改完存回相册又是一次复制,元数据在这来回折腾中丢三落四。
如果只是发朋友圈、发社交平台,用手机 App 图个快没问题。但如果这批图要归档、要交付、要做后续处理,我强烈建议走电脑端,用无损写入的方式处理原始文件。后面讲的命令行方案,本质上就是只改文件头的元数据段,不动像素数据,这是最安全的方式。
4. ExifTool 命令行实操:单张、批量、轨迹匹配全覆盖
轮到正主了。ExifTool 是我这些年用下来最可靠的元数据工具,跨平台、免费、支持格式极全、写入方式无损。它的学习曲线不算陡,关键是理解几个核心参数的逻辑,剩下的都是组合。
4.1 安装与第一条验证命令
Windows 下去官网下那个 exe 包,解压后把exiftool(-k).exe改名成exiftool.exe,放到一个路径里,把这个路径加进系统环境变量 PATH,之后在任意目录都能调用。macOS 用包管理器一行装完,Linux 各发行版仓库里都有,装完直接能用。
装完先别急着写,先学会读:
exiftool -a -G1 -GPS:all photo.jpg-a是显示所有重复标签,-G1是标出每个标签属于哪个组,-GPS:all是只看 GPS 组。输出长这样:
[GPS] GPSVersionID : 2.3.0.0 [GPS] GPSLatitudeRef : North [GPS] GPSLatitude : 30 deg 7' 24.24" [GPS] GPSLongitudeRef : East [GPS] GPSLongitude : 120 deg 34' 2.40" [GPS] GPSAltitude : 12 m看到这个输出,说明文件里已经有 GPS 数据,你要做的是修改;什么都没输出,说明 GPS 段是空的,你要做的是新建。这两种情况的命令完全一样,工具会自动处理,不用你操心。
4.2 单张写入:四个标签缺一不可
给一张没有 GPS 的照片写入坐标,最稳的命令是这样:
exiftool -GPSLatitude=30.1234 -GPSLatitudeRef=N \ -GPSLongitude=120.5678 -GPSLongitudeRef=E \ -GPSAltitude=12 -GPSAltitudeRef=0 \ -GPSMapDatum="WGS-84" \ photo.jpg逐条解释一下为什么这么写。-GPSLatitude后面直接给十进制度数就行,ExifTool 会自动帮你转成度分秒三个有理数,这是它比手写脚本省事的地方。但方向必须单独用-GPSLatitudeRef指定,工具不会从正负号自动推断——你给它 -30.1234,它可能写出一个奇怪的负值,而不是 S。所以负坐标一定要显式写 Ref。
-GPSAltitudeRef=0表示海平面以上,这个标签虽然不影响位置,但缺了它,某些看图软件会把高度显示成空白或者显示成负数。-GPSMapDatum写 WGS-84,是国际通用的地理坐标系,写别的本地坐标系会导致读数偏差几百米。
命令跑完会输出一行1 image files updated,这时候别急着收工,用第一步的查看命令再验证一遍,确认四个标签都在、值都对。我见过太多"更新成功"但方向写反的情况。
还有一个高频坑:网上有些教程让你直接写-GPSPosition=30.1234,120.5678。这个复合标签在某些版本里是只读的,写的时候会报is not writable,或者被静默忽略。稳妥做法永远是拆成四个原子标签,兼容性最好。
4.3 批量写入:CSV 和 GPX 两条路
照片一多,一张张敲命令不现实。ExifTool 支持从 CSV 导入,这是最灵活的批量方式:
SourceFile,GPSLatitude,GPSLatitudeRef,GPSLongitude,GPSLongitudeRef DSC_0001.jpg,30.1234,N,120.5678,E DSC_0002.jpg,30.1256,N,120.5701,E DSC_0003.jpg,30.1289,N,120.5733,Eexiftool -csv=gps.csv -GPSMapDatum="WGS-84" .SourceFile这一列必须是文件的相对路径或绝对路径,跟你在哪个目录执行命令有关。这一步出错是最常见的,文件名对不上,工具会报找不到文件,或者更糟——把坐标写到错误的照片上。所以导入前务必用表格软件核对一遍文件名,尤其是相机自动编号跨了文件夹的情况。
真正体现效率的是 GPX 轨迹匹配:
exiftool -geotag=track.gpx -geosync=+00:02:30 -api GeoMaxExtSecs=3600 ./photos/-geotag指定轨迹文件,工具会读每张照片的拍摄时间,去轨迹里找最接近的点。-geosync是你算出来的时间偏移量,格式是"正负时:分:秒",刚才说的相机慢了四十分钟,这里就写+00:40:00。-api GeoMaxExtSecs=3600是容差,超过这个秒数还匹配不上就跳过,避免把没拍到的照片硬塞一个远处的坐标。默认容差是一千八百秒,户外长时间停留的场景建议调大。
跑完你会在输出里看到每张照片匹配到了哪个时间点、偏了多少秒。这个偏秒数非常值得看,如果大部分照片的偏移都在几十秒以上且方向一致,说明你的-geosync设错了,及时回滚重来比事后发现强。
4.4 借用手机照片的标签,最省事的定点方案
有些场景压根不需要轨迹。比如你去某个地方拍了一组产品图,手机随手拍了一张打卡照,这时候直接把手机那张的 GPS 段复制过来就行:
exiftool -tagsfromfile phone.jpg -GPS:all -overwrite_original camera.jpg-tagsfromfile是"从这个文件复制标签",后面限定了只复制 GPS 组。这个限定非常关键,如果不加-GPS:all,它会把手机照片的相机型号、镜头信息、甚至缩略图全复制过去,结果就是你的相机照片显示成手机拍的,元数据彻底污染,后面想按机型筛选都做不到。
批量版本可以这样,把同一个 GPS 应用到整个目录:
exiftool -tagsfromfile phone.jpg -GPS:all -overwrite_original ./batch/-overwrite_original的作用是不生成xxx.jpg_original备份文件。第一次用的时候千万别加这个参数,让它生成备份,跑完抽查几张确认没问题,再决定要不要清理备份。我吃过这个亏,一条命令批量写错方向,两百多张原图全被覆盖,只能从备份里恢复。
5. 脚本化方案:Python 批量写入与地址反查
命令行能解决九成场景,但有两种情况需要自己写代码:一是你的坐标来源不是 CSV 也不是 GPX,而是一个数据库或者接口;二是你需要在写入的同时做地址反查、按规则生成标签。这时候 Python 加 piexif 是最顺手的选择。
5.1 度分秒转换,别小看这几行
前面说过 GPS 坐标要存成三个有理数。十进制度转度分秒看起来是小学算术,实际写起来坑不少,核心是秒的四舍五入可能导致进位。比如某个坐标算出来是 30 度 7 分 59.99999 秒,四舍五入到四位小数变成 60.0000 秒,这时候必须进位成 30 度 8 分 0 秒,否则写进去的就是一个非法值,某些软件读到会直接放弃解析整段 GPS。
def dec_to_dms(value, precision=10000): value = float(value) deg = int(abs(value)) minutes_f = (abs(value) - deg) * 60 minute = int(minutes_f) sec = (minutes_f - minute) * 60 sec_int = int(round(sec * precision)) if sec_int >= 60 * precision: sec_int = 0 minute += 1 if minute >= 60: minute = 0 deg += 1 return ((deg, 1), (minute, 1), (sec_int, precision))precision=10000表示秒保留四位小数。一秒的纬度距离大约三十一米,四位小数就是零点零三毫米,远远超过实际需要的精度。分母用一万而不是一千万,是为了避免某些老设备的整数溢出。
5.2 完整可跑的批量写入脚本
import piexif from pathlib import Path def write_gps(jpg_path, lat, lon, alt=None): try: exif_dict = piexif.load(str(jpg_path)) except Exception as e: print(f"[跳过] {jpg_path.name} 读取失败: {e}") return False gps = { piexif.GPSIFD.GPSVersionID: (2, 3, 0, 0), piexif.GPSIFD.GPSLatitudeRef: b"N" if lat >= 0 else b"S", piexif.GPSIFD.GPSLatitude: dec_to_dms(lat), piexif.GPSIFD.GPSLongitudeRef: b"E" if lon >= 0 else b"W", piexif.GPSIFD.GPSLongitude: dec_to_dms(lon), piexif.GPSIFD.GPSMapDatum: b"WGS-84", } if alt is not None: gps[piexif.GPSIFD.GPSAltitudeRef] = 0 if alt >= 0 else 1 gps[piexif.GPSIFD.GPSAltitude] = (int(round(abs(alt) * 100)), 100) exif_dict["GPS"] = gps exif_dict["0th"].setdefault(piexif.ImageIFD.Orientation, 1) piexif.insert(piexif.dump(exif_dict), str(jpg_path)) return True if __name__ == "__main__": coords = { "DSC_0001.jpg": (30.1234, 120.5678, 12), "DSC_0002.jpg": (30.1256, 120.5701, 15), } base = Path("./photos") for name, (lat, lon, alt) in coords.items(): p = base / name if not p.exists(): print(f"[缺失] {name}") continue ok = write_gps(p, lat, lon, alt) print(f"[{'完成' if ok else '失败'}] {name}")几个必须注意的点。piexif.insert是直接覆盖原文件的,没有备份机制,所以脚本跑之前务必整个目录复制一份。piexif.load对没有 EXIF 的文件能正常返回空结构,但对 PNG 会直接抛异常——PNG 传统上不支持 EXIF 段,想给 PNG 写坐标得换 WebP 或者走 XMP 侧信道,别在这上面浪费时间。另外exif_dict["0th"]里保留 Orientation 是有原因的,某些工具重写 EXIF 时会把这个标签丢掉,导致竖拍照片被当成横图显示。
5.3 把"地址"也写进去:EXIF 里其实没有地址字段
这是很多人误解的地方。EXIF 的 GPS 段里没有"省市区街道"这种字段,只有经纬度和少量辅助信息。你在某些软件里看到的"拍摄地点:某某路某某号",是软件拿坐标去做了反向查询,实时算出来的,不是存在照片里的。
如果你确实想把文字地址固化到文件里,得写到 IPTC 或者 XMP 段。IPTC 是传统新闻行业的标准,字段老但兼容性好;XMP 是后来基于 XML 的方案,容量大、支持 Unicode。实际做法是两个都写:
exiftool -IPTC:City="某市" -IPTC:Province-State="某省" \ -IPTC:Country-PrimaryLocationName="某地" \ -XMP:City="某市" -XMP:State="某省" -XMP:Country="某地" \ -XMP:Location="某湖畔观景台" \ photo.jpgIPTC:City这些是标准字段,很多相册软件、图片管理系统都认。XMP:Location是自由文本,写什么都行,适合记录"某某观测点"这类具体描述。要注意 IPTC 有字符集问题,中文必须配合-IPTC:CodedCharacterSet=UTF8一起写,否则在部分老软件里会显示成乱码。
如果坐标是从接口批量反查来的地址,在 Python 里对应写exif_dict["0th"]之外还要处理 IPTC 段,piexif 对 IPTC 的支持比较弱,这种情况我一般直接调 ExifTool 命令行,用subprocess传参,比自己拼字节靠谱得多。
6. 常见问题与排查实录
这部分是我这些年被问得最多的问题,整理成速查表,遇到问题先对着表查一遍,能省掉大量试错时间。
6.1 写进去了,但某些软件读不出来
最常见的三种原因,按出现频率排:
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| 系统属性看得到,某看图软件看不到 | 软件读的是 XMP 而非 EXIF | 用-XMP:all查看是否有数据 |
| 手机相册不显示位置 | 系统要求 GPSVersionID 存在 | 补写 2.3.0.0 |
| 全部软件都读不到 | 写入时文件被占用或只读 | 检查文件属性、SD 卡写保护 |
| 显示的位置偏差几十公里 | 度分秒转换错误或方向 Ref 写反 | 对照原始坐标逐项核对 |
| 只有部分照片有坐标 | 批量时文件名匹配失败 | 检查 CSV 里的路径列 |
第二行值得展开说一下。部分手机系统的相册在解析 GPS 时,会检查GPSVersionID是否存在,缺了它就认为这段数据不完整,直接不显示。这个标签不占多少空间,写的时候顺手加上,能避免很多"明明写了却不显示"的困惑。
还有一种情况是文件格式本身不支持。JPEG 支持 EXIF 没问题,TIFF 也支持,但 PNG 传统上不行。现在有些工具会给 PNG 塞一个eXIf块,兼容性参差不齐,指望它在所有平台显示位置不现实。真有需求,转成 WebP 或者直接出 JPEG。
6.2 坐标全乱了,八成是时间没对齐
批量匹配之后发现照片的坐标集中在轨迹的某一段,或者所有照片坐标几乎一样,基本可以断定是时间基准出了问题。排查顺序是这样:先随便挑一张照片,用exiftool -DateTimeOriginal -CreateDate photo.jpg看它的拍摄时间;再打开 GPX 文件,看第一个和最后一个轨迹点的时间范围;两者一比,如果照片时间整体落在轨迹范围之外,那就是偏移量的问题。
用-geosync修正的时候,方向很容易搞反。记住一个原则:这个参数描述的是"照片时间相对于真实时间差了多少"。相机慢了四十分钟,照片上写的时间比真实时间早四十分钟,你要让它往后挪,所以写+00:40:00。不确定就两个方向各试一次,看哪个的匹配偏移秒数更小,这是最快的验证方法。
另外提醒一句,GPX 里的时间是 UTC,如果你的相机设的是本地时间且没做时区换算,-geosync里还得把这八小时算进去。我一般直接把它折算成一个总偏移量,不去纠结是时区问题还是时钟漂移,效果一样。
6.3 发到平台上位置就没了
这不是你的操作问题,是平台的策略。主流社交平台在上传时会对图片重新编码、压缩、剥离元数据,位置信息在服务端就没了。有些平台会单独提供"添加位置"的功能,那是它自己数据库里的一条记录,跟照片文件的 EXIF 没有关系。
所以如果你需要保留坐标做归档,原始文件必须自己留好,别指望从平台上下回来的图还有位置。给客户交付带坐标的照片时,也建议打包成压缩包发原图,而不是让对方去社交平台存图。
6.4 几个容易被忽略的细节
- 只读介质:照片在 SD 卡上时,卡上的写保护开关如果打开了,写入会失败但不一定报错,处理前先复制到本地硬盘。
- 文件被占用:Windows 下如果资源管理器正在生成缩略图,文件可能被锁,写入会报 permission denied,等几秒重试或者换个目录。
- 长路径:路径超过二百六十个字符时,部分工具处理会出问题,批量处理前把目录层级压平。
- 备份文件堆积:不加
-overwrite_original会生成一堆_original后缀的文件,处理完记得清理,不然目录会乱到无法管理。 - 文件修改时间被改:ExifTool 写完会更新文件的修改时间,加
-P参数可以保留原始时间戳,做档案管理时这点很重要。
7. 几个踩过坑之后形成的个人习惯
写到这里技术点基本齐了,最后聊几个不太"技术"但很影响结果的习惯,都是我自己吃亏之后改过来的。
永远不在唯一副本上操作。不管命令多熟、脚本跑过多少次,处理前先把整个目录复制一份出来,或者至少确认有可靠的备份。元数据写入是无损的,但"无损"指的是像素数据,写错了标签覆盖掉原始信息一样找不回来。我有一次偷懒,直接在一个移动硬盘的单份素材上跑批量,方向参数写反,两百多张照片的坐标全反了,幸好那批是试拍,要是正式交付就得重来。
收到别人的照片,先看一眼元数据再处理。有些素材本身就带着错误坐标,比如相机上次连接手机时同步了一个旧位置,之后所有照片都带着这个位置。如果直接在上面覆盖,可能覆盖不干净,残留一些旧标签。稳妥做法是先-GPS:all=清空整个 GPS 段,再写入新值,两步走比一步到位更可靠:
exiftool -GPS:all= -overwrite_original ./batch/ && \ exiftool -csv=gps.csv -GPSMapDatum="WGS-84" ./batch/发布和归档要用两套文件。带精确坐标的照片发到公开平台,等于把自己的活动轨迹公开了,尤其是有固定拍摄习惯的人,几张图一拼就能推出住址和工作地点。我的做法是归档版本保留完整坐标,对外发布前统一跑一遍剥离命令,把 GPS 段清干净再上传。这个动作现在很多平台会自动做,但别指望它,自己动手最稳妥。
坐标系别搞混。国内常用的地图服务在展示时会对坐标做偏移处理,你在网页上读到的经纬度,和照片里应该存的 WGS-84 可能不是一回事。如果坐标是从国内地图工具上取的,直接写进 EXIF 会造成几百米的偏差。判断方法很简单:写入之后找一个能显示 WGS-84 原始坐标的工具对照一下,位置偏了就是坐标系没转。这个坑在给测绘、巡检类项目做归档时特别致命,我现在的习惯是坐标来源和坐标系一起记录在 CSV 里,不靠记忆。
最后一个小技巧。如果一批照片里只有少数几张需要精确定位,别为了这几张去搞整套轨迹记录。用手机在同一位置拍一张,把那张的 GPS 段复制过去,再手工微调偏移量,五分钟能解决的事不要搞成半小时的工程。工具是为人服务的,够用就行。