JPEG 文件損壞常見於傳輸中斷、磁盤錯誤、誤刪恢復等場景。本文提供一個**基於 JPEG 標準文件頭(SOI 標記 0xFFD8)定位並截取有效數據**的輕量修復腳本,適用於文件頭損壞但數據區基本完整的情況。
0xFF 0xD8,文件必須以此兩字節開頭。0xFF 0xE0...0xFF 0xDB,量化表數據。FF D8 FF DB(SOI + DQT)作為**有效數據起始錨點**,假設損壞僅發生在文件開頭。#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
def jpg_fix(filename):
# JPEG 特徵碼:SOI (FFD8) + DQT (FFDB)
signature = b'\xFF\xD8\xFF\xDB'
with open(filename, 'rb') as f:
# 跳過前 4 字節(假設原文件頭可能損壞)
f.seek(len(signature))
data = f.read()
# 尋找特徵碼在數據中的位置
pos = data.find(signature)
if pos < 0:
raise Exception('Not find JPEG signature (FFD8FFDB)')
# 從特徵碼處截取至文件末尾
valid_data = data[pos:]
# 覆寫原文件(建議先備份!)
with open(filename, 'wb') as f:
f.write(valid_data)
print(f'Fixed: {filename}, recovered size: {len(valid_data)} bytes')
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Usage: python jpg_fix.py ")
sys.exit(1)
for arg in sys.argv[1:]:
try:
jpg_fix(arg)
except Exception as e:
print(f"Failed to fix {arg}: {e}")
jpg_fix.py。python jpg_fix.py damaged.jpg
# 批量修復
python jpg_fix.py *.jpg
| 適用 | 不適用 |
|---|---|
| 文件開頭字節損壞/丟失,數據區完整 | 數據區本身損壞、截斷、缺失 |
| 誤寫入文件頭垃圾數據 | 非標準 JPEG 格式(如 RAW、PNG 偽裝) |
| 恢復軟體恢復出的文件頭錯位 | 高度碎片化、多段損壞 |
rb/wb 讀寫,避免文本模式修改換行符。f.seek(4) 跳過原文件前 4 字節(若原文件頭完整則恰好跳過 SOI+DQT)。
3. data.find(signature) 定位第一個有效 JPEG 數據塊起始位置。
4. 截取 data[pos:] 並覆寫,構成合法 JPEG 文件。
FFD8FFE0、SOI+DHT FFD8FFC4 等)。PIL.Image.open().verify())。「特徵碼定位 + 截取尾部」是修復文件頭損壞的經典思路,Python 幾十行代碼即可實現。**修復前務必備份,修復後驗證可打開**,不保證 100% 成功,但能挽回大量看似損壞的珍貴圖片。