首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 讀取照片 EXIF 資訊完整實作:從基礎屬性到攝影參數完整解析

     編輯:PHP 相關知識

PHP exif_read_data() 可深度解析 JPEG/TIFF 影像內嵌的 EXIF 標籤,本文提供完整封裝函式,涵蓋檔案資訊、影像屬性、拍攝參數、版權資訊、縮略圖提取等 60+ 欄位,並處理編碼轉換與缺失值預設。

核心函式架構:GetImageInfo()

<?php
function GetImageInfo(string $imgPath): array {
    // 1. 定義所有枚舉對照表(節選關鍵項)
    $imgType = ['', 'GIF', 'JPG', 'PNG', 'SWF', 'PSD', 'BMP', 'TIFF(II)', 'TIFF(MM)', 'JPC', 'JP2', 'JPX'];
    $orientation = ['', '左上', '右上', '右下', '左下', '左上(旋轉)', '右上(旋轉)', '右下(旋轉)', '左下(旋轉)'];
    $resolutionUnit = ['', '', '英吋', '公分'];
    $exposureProgram = ['未定義', '手動', '標準程式', '光圈優先', '快門優先', '景深優先', '運動', '人像', '風景'];
    $meteringMode = ['0'=>'未知','1'=>'平均','2'=>'中央重點','3'=>'點測','4'=>'分區','5'=>'評估','6'=>'局部','255'=>'其他'];
    $lightSource = ['0'=>'未知','1'=>'日光','2'=>'螢光燈','3'=>'鎢絲燈','10'=>'閃光燈','17'=>'標準A','18'=>'標準B','19'=>'標準C','255'=>'其他'];
    $flash = ['0'=>'未閃光','1'=>'閃光','5'=>'閃光但無回波','7'=>'閃光且有回波'];

    // 2. 讀取 EXIF 資料
    $exif = @exif_read_data($imgPath, 0, true); // 0=所有區塊, true=關聯陣列
    if ($exif === false) {
        return ['錯誤' => '無 EXIF 資料或非支援格式'];
    }

    // 3. 結構化輸出陣列
    $info = [
        '檔案資訊' => '---------------------------',
        '檔名' => $exif['FILE']['FileName'] ?? '未知',
        '檔案類型' => $imgType[$exif['FILE']['FileType'] ?? 0] ?? '未知',
        'MIME型別' => $exif['FILE']['MimeType'] ?? '未知',
        '檔案大小' => ($exif['FILE']['FileSize'] ?? 0) . ' bytes',
        '修改時間' => isset($exif['FILE']['FileDateTime']) ? date('Y-m-d H:i:s', $exif['FILE']['FileDateTime']) : '未知',
        
        '影像資訊' => '---------------------------',
        '圖片說明' => $exif['IFD0']['ImageDescription'] ?? '',
        '製造廠' => $exif['IFD0']['Make'] ?? '',
        '型號' => $exif['IFD0']['Model'] ?? '',
        '方向' => $orientation[$exif['IFD0']['Orientation'] ?? 0] ?? '未知',
        '水平解析度' => ($exif['IFD0']['XResolution'] ?? '') . ($resolutionUnit[$exif['IFD0']['ResolutionUnit'] ?? 0] ?? ''),
        '垂直解析度' => ($exif['IFD0']['YResolution'] ?? '') . ($resolutionUnit[$exif['IFD0']['ResolutionUnit'] ?? 0] ?? ''),
        '建立軟體' => $exif['IFD0']['Software'] ?? '',
        '拍攝時間' => $exif['IFD0']['DateTime'] ?? '',
        '作者' => $exif['IFD0']['Artist'] ?? '',
        '版權' => $exif['IFD0']['Copyright'] ?? '',
        
        '拍攝參數' => '---------------------------',
        'Exif版本' => $exif['EXIF']['ExifVersion'] ?? '',
        '原始拍攝時間' => $exif['EXIF']['DateTimeOriginal'] ?? '',
        '數位化時間' => $exif['EXIF']['DateTimeDigitized'] ?? '',
        '影像寬度' => $exif['COMPUTED']['Width'] ?? '',
        '影像高度' => $exif['COMPUTED']['Height'] ?? '',
        '光圈值 (APEX)' => $exif['EXIF']['ApertureValue'] ?? '',
        '快門速度 (APEX)' => $exif['EXIF']['ShutterSpeedValue'] ?? '',
        '實際F值' => $exif['COMPUTED']['ApertureFNumber'] ?? '',
        '最大光圈' => 'F' . ($exif['EXIF']['MaxApertureValue'] ?? ''),
        '曝光時間' => $exif['EXIF']['ExposureTime'] ?? '',
        'F-Number' => $exif['EXIF']['FNumber'] ?? '',
        '測光模式' => $meteringMode[$exif['EXIF']['MeteringMode'] ?? '0'] ?? '未知',
        '光源' => $lightSource[$exif['EXIF']['LightSource'] ?? '0'] ?? '未知',
        '閃光燈' => $flash[$exif['EXIF']['Flash'] ?? '0'] ?? '未知',
        '曝光模式' => ($exif['EXIF']['ExposureMode'] ?? 0) == 1 ? '手動' : '自動',
        '白平衡' => ($exif['EXIF']['WhiteBalance'] ?? 0) == 1 ? '手動' : '自動',
        '曝光程式' => $exposureProgram[$exif['EXIF']['ExposureProgram'] ?? 0] ?? '未知',
        '曝光補償' => ($exif['EXIF']['ExposureBiasValue'] ?? 0) . ' EV',
        'ISO感光度' => $exif['EXIF']['ISOSpeedRatings'] ?? '',
        '色彩空間' => ($exif['EXIF']['ColorSpace'] ?? 0) == 1 ? 'sRGB' : 'Uncalibrated',
        '焦距' => ($exif['EXIF']['FocalLength'] ?? 0) . ' mm',
        '35mm等效焦距' => ($exif['EXIF']['FocalLengthIn35mmFilm'] ?? 0) . ' mm',
        '對焦距離' => ($exif['COMPUTED']['FocusDistance'] ?? 0) . ' m',
    ];

    // 4. 縮略圖資訊
    if (!empty($exif['COMPUTED']['Thumbnail.FileType'])) {
        $info['縮略圖格式'] = $exif['COMPUTED']['Thumbnail.FileType'];
        $info['縮略圖MIME'] = $exif['COMPUTED']['Thumbnail.MimeType'];
    }

    return $info;
}
?>

前端展示範例:表格 + 縮略圖

<?php
$img = $_GET['img'] ?? '';
if ($img && file_exists($img)) {
    $exif = GetImageInfo($img);
    echo '<table border="1" cellpadding="4" style="border-collapse:collapse;">';
    foreach ($exif as $k => $v) {
        echo "<tr><th style='background:#f0f0f0;'>$k</th><td>$v</td></tr>";
    }
    // 縮略圖輸出
    $thumb = @exif_thumbnail($img);
    if ($thumb !== false) {
        echo '<tr><td colspan="2"><img src="data:' . $exif['縮略圖MIME'] . ';base64,' . base64_encode($thumb) . '" /></td></tr>';
    }
    echo '</table>';
} else {
    echo '請提供有效圖片路徑參數 ?img=path/to.jpg';
}
?>

關鍵技術細節補充

議題處理方式
APEX 單位換算光圈 F值 = 2^(ApertureValue/2);快門秒數 = 2^(-ShutterSpeedValue)
亮度值 (BV) 換算 EVEV = BV + SV,SV = log2(ISO/3.125),ISO100→SV=5
元件配置解碼bin2hex(ComponentsConfiguration) == '01020300' → YCbCr,否則 RGB
使用者註釋編碼前 8 bytes 識別編碼:ASCII/JIS/Unicode/Undefined
檔案來源判斷FileSource == 0x03 → 數位靜態相機

常見問題排查

  • exif_read_data 回傳 false:確認 PHP 編譯含 --enable-exif,且檔案為 JPEG/TIFF 格式(PNG/GIF 不支援 EXIF)。
  • 中文欄位亂碼:EXIF 標準多為 ASCII,部分相機寫入 UTF-16/UTF-8 需手動 mb_convert_encoding()。
  • 大檔案記憶體不足:exif_read_data 會完整載入檔案,超大圖建議先縮圖再讀取。

此實作可直接整合至相簿系統、攝影社群、資產管理平台,完整保留影像背後的技術與創作脈絡。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved