Intro
在數位攝影的世界中,EXIF (Exchangeable Image File Format) 是嵌入在 JPEG、TIFF 等影像檔案中的元資料 (Metadata) 標準。它記錄了照片拍攝時的核心資訊,包含相機型號、光圈、快門、GPS 定位,以及最關鍵的時間標籤:
- DateTimeOriginal (原始拍攝時間):快門按下的那一刻,現代雲端相簿(如 Google 相簿、iCloud)與 NAS(如 Synology Photos)建檔、排序的最核心依據。
- CreateDate (數位化時間):照片被轉換成數位檔案的時間。
- ModifyDate (檔案修改時間):檔案最後一次被編輯或儲存的時間。
當相片缺乏這些內嵌的 EXIF 時間標籤時,作業系統與雲端相簿往往會退而求其次,改用作業系統底層的「檔案建立日期」來排序,這也是導致相簿時空錯亂的元凶。
Exiftool
ExifTool 是由 Phil Harvey 開發、基於 Perl 的開源跨平台命令列應用程式。它是目前對 Metadata 支援度最完整的軟體,能夠讀取、寫入和修改幾乎所有影像與影片格式的元資料。
關於 ExifToolGUI 的限制與硬傷
許多不習慣命令列的工具人會選擇下載圖形介面外殼 ExifToolGUI。雖然它在單張檢視時很方便,但在進行高階批次處理(例如從檔名逆向寫入時間)時卻存在極大的限制:
- 底層參數解析 Bug:GUI 底部的 Command 框(ExifTool direct)在將指令轉發給核心
exiftool.exe時,會在背景對雙引號"、大括號{}與分號;進行二次字串跳脫或強行拆解。 - 防呆機制失靈:這種轉譯干擾會導致 ExifTool 內建的「自動去副檔名」與進階 Perl 正則表達式頻繁翻車,噴出
isn't numeric或Undefined subroutine的警告。
因此,若要執行複雜的字串過濾與時間戳記轉換,直接使用原生的作業系統終端機 (CMD / PowerShell) 才是最穩定的解法。
LINE app 下載照片 meta 被移除問題
從 LINE 下載的照片,原本的 EXIF 拍攝時間會被抹除,但至少留下 microUnixTime 做檔名(例如 1665413902090.jpg),導致丟進 Google 相簿、iPhone 或 NAS 時排序完全錯亂。
Exiftool 解法
以 LINE 照片 1665413902090.jpg 為例:
- 標準 Unix 戳記: 為 10 位數(秒級)。
- LINE 檔名格式: 為 13 位數(microUnixTime 毫秒級),尾巴多出了三位數(
090)。
ExifTool 預設 %s 時間只吃 UnixTime 。因此,完美的解法是:讀取檔名時,利用過濾器強制只擷取前 10 位數,並自動剔除副檔名干擾。
ExifTool 操作流程
將免安裝版 exiftool.exe 放置於工具目錄中(例如 C:\Program Files\Exiftool\),並在照片資料夾開啟終端機,依環境執行以下指令:
- 使用 Windows CMD (傳統黑色視窗)
可以在照片資料夾的路徑,輸入cmd進入 CMD 並同時進入至當前目錄:
"C:\Program Files\Exiftool\exiftool.exe" -d %s -r "-DateTimeOriginal<${filename;m/(\d{10})/;$_=$1}" -overwrite_original .
- 使用 Windows PowerShell / Terminal (新版藍色或黑色視窗)
可以在照片資料夾的路徑,輸入powershell進入 PowerShell 並同時進入至當前目錄
PowerShell 對於大括號與分號極度敏感。為了防止 PowerShell 語法引擎自作聰明搶先轉譯,必須改用單引號 ' 包裹核心參數,並在絕對路徑前加上呼叫運算子 &:
& "C:\Program Files\Exiftool\exiftool.exe" -d %s -r '-DateTimeOriginal<${filename;m/(\d{10})/;$_=$1}' -overwrite_original .
關鍵參數解析
-
-d %s:宣告輸入源為 Unix 時間戳記(秒級)。 -
-r:Recursive 遞迴參數。自動深入當前路徑下的所有「巢狀子資料夾」,批量一次處理。 -
${filename;m/(\d{10})/;$_=$1}:利用 Perl 正則表達式,完美跳過副檔名,並精準抓取檔名前 10 位數(秒級),將其安全投遞給 -DateTimeOriginal。 -
末尾的
.:代表以當前目錄作為遞迴搜索的起點。
影片時間數據規格
照片的拍攝時間主要儲存在 DateTimeOriginal 標籤中,且允許直接寫入當地時間(Local Time)。但現代主流影片格式(如 .mp4、.mov)依據 ISO 14496-12 的規範,其時間標籤與時區解讀有著硬性限制:
- 核心時間標籤:影片不使用
DateTimeOriginal,而是看CreateDate、ModifyDate、MediaCreateDate與TrackCreateDate。 - 強制 UTC 時區(關鍵大坑):國際標準規範要求,影片內嵌的
CreateDate必須強制使用 UTC 零時區時間(格林威治時間)。
案例解析
假設你的影片檔名是台灣時間(GMT+8)的 1665413902(轉換為當地時間是 2022-10-10 22:58:22)。
若你直接將這串時間原封不動寫入 MP4 的 MediaCreateDate 中,當 Google Photos 或 Apple 裝置讀取時,它會預設它是 UTC 時間,並自動加上台灣時區(+8 小時)呈現給你。最終在相簿裡看到的會變成 2022-10-11 06:58:22,硬生生快了 8 小時。
完美的技術解法:我們在讀取檔名時間戳記並寫入影片前,必須透過運算先扣掉 8 小時(28,800 秒)。這樣當各大平台讀取並補回時區差時,相片排序才會完美歸位。
ExifTool 影片專用萬用指令
請在存放影片的資料夾開啟終端機(確保已配置全域路徑或帶入正確的 exiftool.exe 絕對路徑),依環境執行對應指令:
-
使用 Windows CMD (傳統黑色視窗)
"C:\Program Files\Exiftool\exiftool.exe" -ext mp4 -ext mov -d %s -r "-CreateDate<${filename;m/(\d{10})/;$_=$1-28800}" "-ModifyDate<${filename;m/(\d{10})/;$_=$1-28800}" "-TrackCreateDate<${filename;m/(\d{10})/;$_=$1-28800}" "-MediaCreateDate<${filename;m/(\d{10})/;$_=$1-28800}" -overwrite_original . -
使用 Windows PowerShell / Terminal (新版終端機)
為了防止 PowerShell 語法引擎搶先轉譯大括號、分號與減號,必須改用單引號 ' 包裹核心參數,並在絕對路徑前加上呼叫運算子 &:
& "C:\Program Files\Exiftool\exiftool.exe" -ext mp4 -ext mov -d %s -r '-CreateDate<${filename;m/(\d{10})/;$_=$1-28800}' '-ModifyDate<${filename;m/(\d{10})/;$_=$1-28800}' '-TrackCreateDate<${filename;m/(\d{10})/;$_=$1-28800}' '-MediaCreateDate<${filename;m/(\d{10})/;$_=$1-28800}' -overwrite_original .
參數解析
-
-ext mp4 -ext mov:擴充功能過濾器。強制 ExifTool 只捕捉 .mp4 與 .mov 檔案。即使資料夾內混有不需要扣時區的照片(.jpg),也能安全分流處理,不需刻意分開資料夾。 -
$_=$1-28800(技術精髓):透過 Perl Regex 擷取檔名中前 10 位的秒級時間戳記($1)後,在寫入前直接減去 28,800 秒(即 8 小時)。這步操作精準地將台灣當地時間逆向轉換為標準的 UTC 零時區結構。 -
四大標籤:
- Windows 檔案總管 主要讀取 CreateDate 與 ModifyDate。
- Apple 裝置 (iCloud/iOS) 與 Google Photos 則極度依賴 MediaCreateDate 與 TrackCreateDate。
指令一次更新四個標籤,能確保跨平台、跨系統讀取時的絕對相容性。
-
-r與.:遞迴參數與起點標記。自動深入所有巢狀子資料夾進行地毯式大掃描。