php -m | grep gdGIFEncoder.class.php(本文包含完整源碼)frames/ 目錄該類實現了 GIF89a 規範,支持:
構造函數簽名:
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'
);
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());
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,動態生成首選 |
header('Content-Type: image/gif') 在任何輸出前發送,無 BOM、無空白行$GIF_lop,0 只播放一次ob_clean() 及時釋放$anim = new Imagick(); $anim->addImage($frame); $anim->setImageDelay(10); $anim->writeImages('out.gif', true); 功能更強、性能更好GIFEncoder 純 PHP 實現、零依賴,適合輕量級動態生成場景(驗證碼動畫、簡單圖表、狀態演示)。生產環境高性能、高質量需求建議升級 ImageMagick。掌握幀數據獲取(ob_get_contents)、調色盤處理、Netscape 擴展寫入等核心機制,有助於理解動畫編碼本質。