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

PHP 產生 CSS Sprite 合併圖片完整實作(自動掃描目錄、生成樣式表)

     編輯:PHP 相關知識

什麼是 CSS Sprite?

CSS Sprite(CSS 精靈圖)是將多張小圖片合併為一張大圖,再透過 background-position 定位顯示,減少 HTTP 請求數、提升頁面載入速度的經典前端優化技術。

PHP 自動化產生 Sprite 流程

  1. 掃描指定目錄所有 PNG 圖片。
  2. 計算合併後總寬度、最大高度。
  3. 建立真彩畫布(支援透明度),依序水平貼上各圖片。
  4. 記錄每張圖片的 X 座標、寬高,生成對應 CSS 類別。
  5. 輸出合併圖片(sprite.png)與樣式表(sprite.css)。

完整實作程式碼

<?php
/**
 * 自動生成水平排列 CSS Sprite
 * @param string $srcDir  來源圖片目錄(結尾需含 /)
 * @param string $prefix  CSS 類別前綴(如 'icon-')
 * @param string $dstBase 輸出檔名基礎(不含副檔名),預設 'sprite'
 */
function generateSprite(string $srcDir, string $prefix = 'icon-', string $dstBase = 'sprite'): void {
    // 1. 掃描 PNG 檔案
    $files = glob($srcDir . '*.png');
    if (empty($files)) {
        throw new RuntimeException("No PNG files found in $srcDir");
    }
    sort($files); // 確保順序穩定

    // 2. 計算畫布尺寸
    $totalWidth = 0;
    $maxHeight  = 0;
    $imgInfos   = [];
    foreach ($files as $file) {
        $info = getimagesize($file);
        if (!$info || $info['mime'] !== 'image/png') continue;
        $imgInfos[$file] = ['w' => $info[0], 'h' => $info[1]];
        $totalWidth += $info[0];
        $maxHeight = max($maxHeight, $info[1]);
    }

    // 3. 建立透明畫布
    $canvas = imagecreatetruecolor($totalWidth, $maxHeight);
    imagesavealpha($canvas, true);
    $transparent = imagecolorallocatealpha($canvas, 0, 0, 0, 127);
    imagefill($canvas, 0, 0, $transparent);

    // 4. 依序貼圖並生成 CSS
    $cssRules = [];
    $x = 0;
    foreach ($imgInfos as $file => $info) {
        $src = imagecreatefrompng($file);
        imagecopy($canvas, $src, $x, 0, 0, 0, $info['w'], $info['h']);
        imagedestroy($src);

        $name = pathinfo($file, PATHINFO_FILENAME);
        $class = $prefix . $name;
        $cssRules[] = ".$class { width: {$info['w']}px; height: {$info['h']}px; background-position: -{$x}px 0; }";
        $x += $info['w'];
    }

    // 5. 輸出合併圖片
    $pngPath = $dstBase . '.png';
    imagepng($canvas, $pngPath);
    imagedestroy($canvas);

    // 6. 生成 CSS 檔案
    $cssContent = ".$prefix" . "* { background-image: url('$pngPath'); background-repeat: no-repeat; display: inline-block; }\n";
    $cssContent .= implode("\n", $cssRules) . "\n";
    file_put_contents($dstBase . '.css', $cssContent);

    echo "Generated: $pngPath, {$dstBase}.css (" . count($cssRules) . " icons)\n";
}

// 使用範例
generateSprite(__DIR__ . '/assets/icons/', 'ic-', 'sprite');
?>

生成的 CSS 結構示例

.ic-* { background-image: url('sprite.png'); background-repeat: no-repeat; display: inline-block; }
.ic-home { width: 24px; height: 24px; background-position: -0px 0; }
.ic-user { width: 24px; height: 24px; background-position: -24px 0; }
.ic-setting { width: 24px; height: 24px; background-position: -48px 0; }

HTML 使用方式

<link rel="stylesheet" href="sprite.css">
<i class="ic-home"></i>
<i class="ic-user"></i>
<i class="ic-setting"></i>

進階優化與擴充

  • 垂直/網格排列:修改貼圖座標邏輯($x, $y),適合寬度受限容器。
  • 支援 JPEG/WebP:依 mime 呼叫 imagecreatefromjpeg/webp,輸出時可選 imagewebp。
  • Retina/@2x 支援:準備 2x 圖片,生成 @media (-webkit-min-device-pixel-ratio: 2) 區塊指向 sprite@2x.png。
  • 整合建構工具:現代專案建議改用 css-sprite、PostCSS Sprite、Webpack Sprite Loader 等建構時期工具,避免執行期產生檔案、利用快取、支援來源映射。
  • 清理舊檔:部署腳本中加入刪除舊 sprite*.png/.css,避免殘留。

常見坑點

  • PHP GD 未啟用 --with-freetype、--with-webp 導致函式不存在。
  • 圖片過大導致記憶體耗盡:ini_set('memory_limit', '256M') 或分批處理。
  • 輸出目錄無寫入權限:確保 Web 使用者(www-data、nginx)對目標目錄有寫入權。
  • CSS 路徑錯誤:若 CSS 與圖片不在同目錄,需調整 background-image: url() 路徑。

結語

PHP 產生 CSS Sprite 適合舊專案、動態圖示庫、無 Node.js 建構環境的場景。現代前端工程建議納入建構流程(Vite/Webpack/Rollup 插件),實現零執行期成本、自動快取清除、TypeScript 型別安全。理解原理有助於在受限環境快速落地優化。

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