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

PHP 生成 GIF 動畫完整教程:GIFEncoder 類實戰與兩大應用場景

     編輯:PHP 相關知識

前置準備

  1. 確認 GD 擴展已安裝並啟用:php -m | grep gd
  2. 下載 GIFEncoder.class.php(本文包含完整源碼)
  3. 合成模式需將幀圖片放入 frames/ 目錄

核心類:GIFEncoder

該類實現了 GIF89a 規範,支持:

  • 多幀合成(URL 或二進制數據源)
  • 循環控制、幀延遲、處置方式
  • 透明色設置、全局/局部調色盤處理
  • Netscape 循環擴展塊寫入

構造函數簽名:

new GIFEncoder(
    $GIF_src,      // 幀源數組(文件路徑或二進制數據)
    $GIF_dly,      // 每幀延遲數組(百分之一秒)
    $GIF_lop,      // 循環次數(-1=無限,0=一次)
    $GIF_dis,      // 處置方式(0=無, 1=不處置, 2=背景還原, 3=上一幀)
    $GIF_red,      // 透明色 R
    $GIF_grn,      // 透明色 G
    $GIF_blu,      // 透明色 B
    $GIF_mod       // 源類型:'url' 或 'bin'
);

場景一:現有圖片合成 GIF

include 'GIFEncoder.class.php';

$frames = [];
$delays = [];
$dir = 'frames/';
if ($dh = opendir($dir)) {
    while (($file = readdir($dh)) !== false) {
        if ($file !== '.' && $file !== '..') {
            $frames[] = $dir . $file;
            $delays[] = 5;  // 50ms/幀 = 20fps
        }
    }
    closedir($dh);
}

$gif = new GIFEncoder($frames, $delays, 0, 2, 0, 0, 0, 'url');

header('Content-Type: image/gif');
echo $gif->GetAnimation();

// 或存檔:
// file_put_contents('animation.gif', $gif->GetAnimation());

場景二:動態繪製生成 GIF(彈球動畫)

include 'GIFEncoder.class.php';

ob_start();  // 捕獲 imagegif 輸出

$board_w = 60; $board_h = 60;
$pad_w = 5; $pad_h = 15;
$ball = 5;
$game_w = $board_w - 2*$pad_w - $ball;
$game_h = $board_h - $ball;

$x = 0; $y = rand(0, $game_h);
$xv = rand(1, 10); $yv = rand(1, 10);
$path = [[$x, $y]];

// 計算完整軌跡(直到回到起點)
do {
    $x += $xv; $y += $yv;
    if ($x > $game_w) { $xv = -$xv; $x = $game_w - ($x - $game_w); }
    elseif ($x < 0) { $xv = -$xv; $x = -$x; }
    if ($y > $game_h) { $yv = -$yv; $y = $game_h - ($y - $game_h); }
    elseif ($y < 0) { $yv = -$yv; $y = -$y; }
    $path[] = [$x, $y];
} while ($x !== $path[0][0] || $y !== $path[0][1]);

$frames = [];
foreach ($path as $i => $pt) {
    $img = imagecreate($board_w, $board_h);
    $black = imagecolorallocate($img, 0, 0, 0);
    $white = imagecolorallocate($img, 255, 255, 255);
    $red = imagecolorallocate($img, 255, 0, 0);

    // 左邊板
    $py = min($pt[1], $board_w - $pad_h);
    imagefilledrectangle($img, 0, $py, $pad_w, $py + $pad_h, $white);
    // 右邊板
    imagefilledrectangle($img, $board_w - $pad_w, 0, $board_w, $board_h, $red);
    // 球
    imagefilledrectangle($img, 
        $pad_w + $pt[0], $pt[1], 
        $pad_w + $pt[0] + $ball, $pt[1] + $ball, $white
    );

    imagegif($img);
    imagedestroy($img);
    $frames[] = ob_get_contents();
    ob_clean();
}

$gif = new GIFEncoder($frames, array_fill(0, count($frames), 10), 0, 2, 0, 0, 1, 'bin');

header('Content-Type: image/gif');
echo $gif->GetAnimation();

關鍵參數調優建議

參數建議值說明
循環次數0 (無限)大多數 Web 動畫期望無限循環
處置方式2 (背景還原)避免幀疊加殘影
幀延遲10-20 (100-200ms)太快瀏覽器可能限制,太慢不流暢
透明色設置具體 RGB僅當幀有透明背景時需要
源模式'bin' (內存數據)避免磁盘 I/O,動態生成首選

常見問題排查

  1. 輸出亂碼:確保 header('Content-Type: image/gif') 在任何輸出前發送,無 BOM、無空白行
  2. 動畫靜止:檢查循環參數 $GIF_lop,0 只播放一次
  3. 顏色錯誤:GIF 限 256 色,複雜漸變會抖動,考慮 PNG/APNG 或 WebP
  4. 內存溢出:大量幀用 'bin' 模式 + ob_clean() 及時釋放

現代替代方案

  • ImageMagick (imagick):$anim = new Imagick(); $anim->addImage($frame); $anim->setImageDelay(10); $anim->writeImages('out.gif', true); 功能更強、性能更好
  • FFmpeg:視頻轉 GIF、高壓縮比
  • WebP 動畫:體積更小、支持 24 位色 + Alpha,現代瀏覽器全支持

總結

GIFEncoder 純 PHP 實現、零依賴,適合輕量級動態生成場景(驗證碼動畫、簡單圖表、狀態演示)。生產環境高性能、高質量需求建議升級 ImageMagick。掌握幀數據獲取(ob_get_contents)、調色盤處理、Netscape 擴展寫入等核心機制,有助於理解動畫編碼本質。

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