JPEG 格式有兩種存儲方式:Baseline JPEG(基線/順序式) 與 Progressive JPEG(漸進式)。兩者文件大小、圖像數據、副檔名完全相同,唯一區別在於顯示渲染方式。本文詳解兩者差異,並提供 PHP GD 庫一鍵轉換代碼與驗證方法。
利用 GD 庫的 imageinterlace() 函數即可實現轉換:
<?php
// 1. 從文件創建圖像資源
$im = imagecreatefromjpeg('file.jpg');
// 2. 關鍵步驟:開啟隔行掃描(漸進式)
// 參數 1 表示開啟,0 表示關閉
imageinterlace($im, 1);
// 3. 輸出新文件,第三參數 80 為質量(0-100)
imagejpeg($im, './outfile.jpg', 80);
// 4. 釋放資源
imagedestroy($im);
?>
說明: imageinterlace($im, 1) 設置隔行掃描標記,輸出時自動生成 Progressive JPEG。質量參數建議 75-85 平衡體積與清晰度。
<?php
function convertToProgressive($srcDir, $dstDir, $quality = 80) {
if (!is_dir($dstDir)) mkdir($dstDir, 0755, true);
$files = glob($srcDir . '/*.{jpg,jpeg,JPG,JPEG}', GLOB_BRACE);
foreach ($files as $file) {
$im = @imagecreatefromjpeg($file);
if (!$im) continue;
imageinterlace($im, 1);
$filename = basename($file);
imagejpeg($im, $dstDir . '/' . $filename, $quality);
imagedestroy($im);
echo "Converted: $filename\n";
}
}
convertToProgressive('./images', './progressive_images', 80);
?>
identify -verbose outfile.jpg
輸出中查找 Interlace 字段:
Interlace: JPEG 或 Interlace: Line → Progressive JPEGInterlace: None → Baseline JPEG<?php
function isProgressiveJpeg($filename) {
$data = file_get_contents($filename, false, null, 0, 12); // 讀取頭部
// 檢查 SOF 標記 (0xFFC0 Baseline, 0xFFC2 Progressive)
// 簡易檢測:搜索 0xFFC2 標記
return strpos($data, chr(0xFF).chr(0xC2)) !== false;
}
var_dump(isProgressiveJpeg('outfile.jpg')); // true/false
?>
Network 面板查看圖片響應頭 Content-Type: image/jpeg 無法區分。需配合上述工具或觀察加載行為:模糊→清晰為 Progressive。
若項目允許,強烈建議直接轉換為 WebP(支持有損/無損、透明、動畫)或 AVIF(更高壓縮比):
<?php
// PHP 7.0+ GD 支持 WebP
$im = imagecreatefromjpeg('file.jpg');
imagewebp($im, 'file.webp', 80); // 質量 80
imagedestroy($im);
// 瀏覽器端使用 標籤兼容
/>
<picture>
<source type="image/webp" srcset="file.webp">
<img src="file.jpg" alt="Fallback">
</picture>
Progressive JPEG 以極低成本(一行代碼)顯著提升大圖加載體驗,是圖片優化的「必做項」。PHP GD 的 imageinterlace($im, 1) 讓轉換毫無門檻。配合 ImageMagick 驗證,構建自動化圖片處理流水線,讓用戶告別「一行行加載」的等待。