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

PHP 服務端圖片縮略圖自動生成實作(支援等比縮放、填充背景)

     編輯:PHP 綜合知識

透過 Apache/Nginx 的 404 錯誤處理機制,將不存在的縮略圖請求導向 PHP 腳本即時生成並快取,實現「按需生成、永久快取」的圖片服務架構。

核心邏輯流程

  1. 解析請求 URL:/image/{name}_w{width}_h{height}.{ext}
  2. 驗證尺寸是否在允許清單(如 100x100, 200x100)。
  3. 讀取原圖 {name}.{ext},支援 JPEG/PNG/GIF。
  4. 等比縮放:以目標長寬比為準,長邊貼齊,短邊留白(白色背景)。
  5. 輸出圖片並同時寫入快取檔案,下次直接由 Web Server 靜態服務。

完整程式碼(僅支援 JPEG 示範,可擴充)

<?php
// 允許的縮略圖尺寸
$allowedSizes = [
    '100_100' => true,
    '200_100' => true,
];
$imageRoot = __DIR__ . '/../image/';

// 解析請求檔名
$requestUri = $_SERVER['REQUEST_URI'];
$fileName   = basename($requestUri);

// 正則解析:name_w{width}_h{height}.ext
if (!preg_match('/(?P<name>[\w-]+)_w(?P<width>\d+)_h(?P<height>\d+)\.(?P<ext>\w+)/', $fileName, $m)) {
    header('HTTP/1.0 404 Not Found');
    exit('Invalid thumbnail spec');
}

$sizeKey = $m['width'] . '_' . $m['height'];
if (!isset($allowedSizes[$sizeKey])) {
    header('HTTP/1.0 404 Not Found');
    exit('Size not allowed');
}

$srcPath = $imageRoot . $m['name'] . '/' . $m['name'] . '.' . $m['ext'];
if (!is_file($srcPath)) {
    header('HTTP/1.0 404 Not Found');
    exit('Source image not found');
}

// 載入原圖
switch (strtolower($m['ext'])) {
    case 'jpg':
    case 'jpeg':
        $srcImg = imagecreatefromjpeg($srcPath);
        break;
    case 'png':
        $srcImg = imagecreatefrompng($srcPath);
        break;
    case 'gif':
        $srcImg = imagecreatefromgif($srcPath);
        break;
    default:
        header('HTTP/1.0 404 Not Found');
        exit('Unsupported format');
}

$srcW = imagesx($srcImg);
$srcH = imagesy($srcImg);
$dstW = (int)$m['width'];
$dstH = (int)$m['height'];

// 等比縮放計算
$ratioSrc = $srcW / $srcH;
$ratioDst = $dstW / $dstH;
if ($ratioSrc > $ratioDst) {
    // 原圖較寬:以寬為準
    $newW = $dstW;
    $newH = (int)($dstW / $ratioSrc);
} else {
    // 原圖較高:以高為準
    $newH = $dstH;
    $newW = (int)($dstH * $ratioSrc);
}

// 建立目標畫布(白底)
$dstImg = imagecreatetruecolor($dstW, $dstH);
$white  = imagecolorallocate($dstImg, 255, 255, 255);
imagefilledrectangle($dstImg, 0, 0, $dstW - 1, $dstH - 1, $white);

// 置中貼上縮圖
$offsetX = (int)(($dstW - $newW) / 2);
$offsetY = (int)(($dstH - $newH) / 2);
imagecopyresampled($dstImg, $srcImg, $offsetX, $offsetY, 0, 0, $newW, $newH, $srcW, $srcH);

// 輸出並快取
$cacheDir  = $imageRoot . $m['name'] . '/';
$cachePath = $cacheDir . $fileName;
if (!is_dir($cacheDir)) {
    mkdir($cacheDir, 0755, true);
}

header('Content-Type: image/jpeg');
imagejpeg($dstImg, $cachePath, 90); // 同時存檔
imagejpeg($dstImg, null, 90);       // 輸出瀏覽器

imagedestroy($srcImg);
imagedestroy($dstImg);
?>

Web Server 設定要點

  • Apache:ErrorDocument 404 /thumbnail.php(或用 mod_rewrite 判斷檔案不存在時導向)。
  • Nginx:error_page 404 /thumbnail.php; 搭配 try_files。
  • 生成後的快取檔案下次請求將直接由 Web Server 服務,不再經由 PHP,效能極佳。

擴充建議

  • 加入 ETag / Last-Modified / Cache-Control 標頭。
  • 支援 WebP/AVIF 輸出(imagewebp())。
  • 整合圖片處理庫,提供裁切、濾鏡、水印等進階功能。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved