推荐使用exiftool-vendored,它是唯一能可靠读写完整Exif、XMP、IPTC且跨平台的方案,基于Perl exiftool二进制封装,支持JPEG/TIFF等格式,适合Node.js环境下的稳定生产使用。

使用一条命令部署ProbeChain Rydberg测试网代理节点。自动注册为Agent(NodeType=1),免gas,支持macOS/Linux/Windows。触发词:/r
Node.js 读取图片 Exif 信息要用哪个库?
Exif 数据是嵌入在 JPEG/TIFF 文件中的元数据,Node.js 原生不支持解析,必须依赖第三方库。目前最稳定、维护活跃、支持写入的只有 exiftool-vendored(基于 Perl 的 exiftool 二进制封装)和 piexifjs(纯 JS,仅支持 JPEG 且写入能力有限)。
exiftool-vendored 是唯一能可靠读写完整 Exif、XMP、IPTC 且跨平台的方案,尤其适合 VSCode 中调试 Node 脚本时使用。
piexifjs 不支持 PNG、HEIC、RAW,写入时容易损坏 JPEG 结构,遇到 Invalid JPEG format 错误基本就是它导致的。
推荐直接安装:
npm install exiftool-vendored注意:首次运行会自动下载对应平台的
exiftool 二进制(约 15MB),需确保网络通畅;若公司内网限制,可手动下载 exiftool 并通过 EXIFTOOL_PATH 环境变量指定路径。
VSCode 中调试 Exif 修改脚本常见报错及修复
在 VSCode 终端或调试器中运行时,常遇到以下问题:
-
Error: spawn exiftool ENOENT:说明 exiftool 未正确安装或 PATH 未生效。检查 node_modules/exiftool-vendored/bin/ 下是否存在可执行文件(如 exiftool.exe 或 exiftool),Windows 用户需确认 VSCode 终端是否为 PowerShell/CMD(而非 Git Bash,后者可能找不到 Windows 二进制)
-
ExifTool not found or not executable:尝试显式传入路径:const ExifTool = require("exiftool-vendored").ExifTool; const exiftool = new ExifTool({ taskTimeoutMillis: 10000, maxProcs: 1 });
- 修改后图片打不开:多数因写入了非法值(如
DateTimeOriginal 格式不是 YYYY:MM:DD HH:MM:SS),或试图写入只读标签(如 ExifVersion)。可用 exiftool -list 查看哪些标签可写
读取并安全修改 JPEG 的 DateTimeOriginal 和 GPS 坐标
这是最典型需求——批量修正拍摄时间或地理标记。关键点在于:
- 读取用
exiftool.read(),返回 Promise,结果是扁平对象(键名如 DateTimeOriginal、GPSLatitude),不是嵌套结构
- 写入必须用
exiftool.write(),且传入对象键名要严格匹配 ExifTool 官方标签名(区分大小写),例如 GPSLatitude 不能写成 gpsLatitude
- GPS 坐标必须为度分秒格式字符串(如
"39.9042° N")或十进制度数(39.9042),但后者需配合 GPSLatitudeRef 和 GPSLongitudeRef 才能被正确识别
- 修改时间建议用
DateTimeOriginal + ModifyDate 双写,避免部分看图软件只读前者
const { ExifTool } = require("exiftool-vendored");
const exiftool = new ExifTool();
async function fixPhoto(path) {
try {
const tags = await exiftool.read(path);
console.log("原始时间:", tags.DateTimeOriginal);
await exiftool.write(path, {
DateTimeOriginal: "2023:05:20 14:30:00",
ModifyDate: "2023:05:20 14:30:00",
GPSLatitude: 39.9042,
GPSLatitudeRef: "N",
GPSLongitude: 116.4074,
GPSLongitudeRef: "E"
});
} finally {
exiftool.end(); // 必须调用,否则子进程残留
}
}
为什么不能用 fs.readFile + Buffer 解析 Exif?
有人试图用 fs.readFileSync 读取 JPEG 二进制,再按 JPEG APP1 段手动解析——这极其危险。原因包括:
- JPEG 中 Exif 可能位于多个 APPn 段(不止 APP1),也可能被压缩或加密(如 iPhone HEIC 封装)
- 写入时若只改 APP1 段而忽略其他关联段(如 XMP),会导致元数据不一致,Photos.app 或 Lightroom 直接丢弃
- Exif 标签存在多种编码(ASCII、UTF-8、UNICODE)、字节序(Motorola/Intel),手动处理极易出错
-
exiftool-vendored 内部做了大量容错:自动重写整个 JPEG 结构、校验 CRC、保留原始缩略图、同步更新 XMP
真正需要“轻量”场景(如浏览器端预览)才考虑 piexifjs,但 Node 环境下,绕过 exiftool 就是给自己埋兼容性雷。
哪怕只是改一个时间戳,也要走完整工具链——Exif 不是键值对,是带约束的二进制协议。
Error: spawn exiftool ENOENT:说明 exiftool 未正确安装或 PATH 未生效。检查 node_modules/exiftool-vendored/bin/ 下是否存在可执行文件(如 exiftool.exe 或 exiftool),Windows 用户需确认 VSCode 终端是否为 PowerShell/CMD(而非 Git Bash,后者可能找不到 Windows 二进制)ExifTool not found or not executable:尝试显式传入路径:const ExifTool = require("exiftool-vendored").ExifTool; const exiftool = new ExifTool({ taskTimeoutMillis: 10000, maxProcs: 1 });DateTimeOriginal 格式不是 YYYY:MM:DD HH:MM:SS),或试图写入只读标签(如 ExifVersion)。可用 exiftool -list 查看哪些标签可写- 读取用
exiftool.read(),返回 Promise,结果是扁平对象(键名如DateTimeOriginal、GPSLatitude),不是嵌套结构 - 写入必须用
exiftool.write(),且传入对象键名要严格匹配 ExifTool 官方标签名(区分大小写),例如GPSLatitude不能写成gpsLatitude - GPS 坐标必须为度分秒格式字符串(如
"39.9042° N")或十进制度数(39.9042),但后者需配合GPSLatitudeRef和GPSLongitudeRef才能被正确识别 - 修改时间建议用
DateTimeOriginal+ModifyDate双写,避免部分看图软件只读前者
const { ExifTool } = require("exiftool-vendored");
const exiftool = new ExifTool();
async function fixPhoto(path) {
try {
const tags = await exiftool.read(path);
console.log("原始时间:", tags.DateTimeOriginal);
await exiftool.write(path, {
DateTimeOriginal: "2023:05:20 14:30:00",
ModifyDate: "2023:05:20 14:30:00",
GPSLatitude: 39.9042,
GPSLatitudeRef: "N",
GPSLongitude: 116.4074,
GPSLongitudeRef: "E"
});
} finally {
exiftool.end(); // 必须调用,否则子进程残留
}
}
为什么不能用 fs.readFile + Buffer 解析 Exif?
有人试图用 fs.readFileSync 读取 JPEG 二进制,再按 JPEG APP1 段手动解析——这极其危险。原因包括:
- JPEG 中 Exif 可能位于多个 APPn 段(不止 APP1),也可能被压缩或加密(如 iPhone HEIC 封装)
- 写入时若只改 APP1 段而忽略其他关联段(如 XMP),会导致元数据不一致,Photos.app 或 Lightroom 直接丢弃
- Exif 标签存在多种编码(ASCII、UTF-8、UNICODE)、字节序(Motorola/Intel),手动处理极易出错
-
exiftool-vendored 内部做了大量容错:自动重写整个 JPEG 结构、校验 CRC、保留原始缩略图、同步更新 XMP
真正需要“轻量”场景(如浏览器端预览)才考虑 piexifjs,但 Node 环境下,绕过 exiftool 就是给自己埋兼容性雷。
哪怕只是改一个时间戳,也要走完整工具链——Exif 不是键值对,是带约束的二进制协议。
exiftool-vendored 内部做了大量容错:自动重写整个 JPEG 结构、校验 CRC、保留原始缩略图、同步更新 XMP

















