[Node.js]讀取JPEG相片EXIF資訊中的GPS和時間戳記

一些網站,如google photo,上傳相片後,會抓取偵測你的相片中的EXIF(Exchangeable image file format),自動得使用時間戳記資訊並歸類到合適的位置。以前我是使用exiv2指令操作或複製exif資訊,這篇整理使用Node.js程式取出EXIF的GPS與時間戳記,時間戳記還會轉換有時區資訊的Date物件。




安裝套件

npm install exif


程式碼

import exif from 'exif';

const ARGS = process.argv.slice(2);

if (ARGS.length < 1) {
console.error(`given 1 arg, usage: node ${process.argv[1]} <input-image-path>`)
process.exit(1);
}

// 從第一個參數取的照片檔案路徑
const photoPath = ARGS[0];

// 從指定路徑取得exif資訊, 這是一個async函數
function readExifFromPathAsync(image) {
return new Promise((resolve, reject) => {
new exif.ExifImage({ image }, (error, exifData) => {
error ? reject(error) : resolve(exifData);
})
})
}

// 將timestamp字串轉換成Date
function exifTS2Date(timestamp, timezone) {
// 時間戳記字串格式是 YYYY:MM:DD HH:MM:SS
const regex = /^(\d{4}):(\d{2}):(\d{2})[T ](\d{2}:\d{2}:\d{2})$/;

// 確認格式並解構
const result = timestamp.match(regex);
if (!result) {
throw new Error('不合乎規則的 EXIF 時間戳記字串格式');
}

const t = timezone % 12;
const z = !t ? 'Z' : ((t > 0 ? '+' : '-') + (Math.abs(t) <= 9 ? '0' : '') + `${t}:00`);

// 組合成ISO時間字串
const isostr = `${result[1]}-${result[2]}-${result[3]}T${result[4]}${z}`;
return new Date(isostr);
}

// EXIf = Exchangeable image file format
try {
const exifData = await readExifFromPathAsync(photoPath);

// 印出所有 EXIF 資訊
console.debug(exifData);

// 取出 GPS 資訊
// 為 EXIF 的 GPSLatitude 與 GPSLongitude 欄位
if (exifData.gps) {
const gpsInfo = {
// 緯度,南北,單位:a° b' c" N或S
latitude: exifData.gps.GPSLatitude,
// 經度,東西,單位:a° b' c" E或W
longitude: exifData.gps.GPSLongitude,
};
console.log('GPS資訊:', gpsInfo);
} else {
console.log('沒有GPS資訊');
}

// 取出時間戳記 (timestamp) 資訊
// 為 EXIF 的 DateTimeOriginal 欄位
const timestamp = exifData.exif.DateTimeOriginal;
console.log('時間戳記:', timestamp, ' Date物件:', exifTS2Date(timestamp, 8).toString());
} catch (error) {
console.log('發生錯誤: ' + error.message);
}

留言