Skip to content

图片 EXIF 信息处理

什么是 EXIF

EXIF(Exchangeable Image File Format)是照片的元数据,包括:拍摄时间、GPS 经纬度、相机型号、光圈快门、图片方向等。

前端读取 EXIF

推荐:ExifReader(现代方案)

bash
npm install exifreader
js
import ExifReader from 'exifreader';
const tags = ExifReader.load(await file.arrayBuffer());
// tags['GPSLatitude'].description → "48° 51' 28.57\" N"

fileBuffer 类型为 ArrayBuffer,可从 File 或 Blob 的 .arrayBuffer() 获取。

备选:exif-js(已废弃,仅兼容旧项目)

⚠️ exif-js 自 2017 年停更,新项目请用 ExifReader。

js
import EXIF from 'exif-js';

const img = document.getElementById('preview');
EXIF.getData(img, function() {
  const lat = EXIF.getTag(this, 'GPSLatitude');     // 纬度
  const lon = EXIF.getTag(this, 'GPSLongitude');    // 经度
  const orientation = EXIF.getTag(this, 'Orientation'); // 方向
});

微信小程序中的 EXIF

核心问题:iOS 端压缩图片会丢弃 EXIF 信息。

踩坑记录:

  1. wx.chooseImage + sizeType: ['original'] 可保留部分 EXIF,但大于约 5MB 或宽高超过 4096px 的图片可能被自动压缩
  2. wx.chooseMedia 在真机上(微信 8.0.27 版本)获取的经纬度为空,开发者工具正常——这是微信已知 Bug
  3. 从聊天记录选文件(wx.chooseMessageFile)可获取原始文件,不会丢失 EXIF

推荐方案:

  • 需要 GPS:引导用户使用"从聊天记录选择",或使用 wx.getLocation 直接获取
  • 需要方向信息:可使用 exif-js(仅兼容旧项目时)在前端读取 Orientation,自动旋转到正确方向
  • 压缩时保留 EXIF:先将 EXIF 信息提取保存,压缩后在 Canvas 输出前写回

EXIF GPS 坐标转换

EXIF 中的 GPS 坐标是度分秒格式:

GPSLatitude: [30, 35, 24.5]  // 30°35'24.5"
GPSLatitudeRef: "N"           // 北纬

转换为小数度数:

js
function toDecimal(dms, ref) {
  if (!Array.isArray(dms) || dms.length < 3) return null;
  const d = Number(dms[0]) + Number(dms[1]) / 60 + Number(dms[2]) / 3600;
  return ref === 'S' || ref === 'W' ? -d : d;
}

配合高德/百度地图 API 可实现逆地理编码(经纬度 → 地址)。

Released under the MIT License.