GD 庫簡介
GD (Graphics Draw) 是 PHP 內建的圖形處理擴充,支援建立、修改、輸出 PNG/JPEG/GIF/WebP 等格式。常用於:驗證碼生成、縮圖、水印、統計圖表、圖片合成。
確認啟用:php -m | grep gd 或 phpinfo() 查看 GD Support => enabled。
核心函數分類速查
1. 圖片建立與載入
| 函數 | 說明 |
imagecreatetruecolor(int $w, int $h) | 建立真彩色畫布 (推薦) |
imagecreate(int $w, int $h) | 建立調色盤模式畫布 (舊版) |
imagecreatefrompng|jpeg|gif|webp|wbmp|bmp(string $file) | 從檔案/字串載入 |
imagecreatefromstring(string $data) | 從二進位字串載入 |
2. 顏色管理
| 函數 | 說明 |
imagecolorallocate($im, $r, $g, $b) | 分配顏色,回傳索引 |
imagecolorallocatealpha($im, $r, $g, $b, $alpha) | 分配帶透明度顏色 (0-127) |
imagecolortransparent($im, $colorIndex) | 設定透明色 |
imagecolorresolve($im, $r, $g, $b) | 取得最接近顏色索引 (不失敗) |
imagecolorsforindex($im, $index) | 取得索引對應的 RGB 陣列 |
3. 基礎繪圖
| 函數 | 說明 |
imagesetpixel($im, $x, $y, $color) | 畫點 |
imageline($im, $x1, $y1, $x2, $y2, $color) | 畫直線 |
imagedashedline($im, $x1, $y1, $x2, $y2, $color) | 畫虛線 |
imagerectangle($im, $x1, $y1, $x2, $y2, $color) | 畫矩形框 |
imagefilledrectangle($im, $x1, $y1, $x2, $y2, $color) | 畫實心矩形 |
imageellipse($im, $cx, $cy, $w, $h, $color) | 畫橢圓/圓 |
imagefilledellipse($im, $cx, $cy, $w, $h, $color) | 畫實心橢圓 |
imagearc($im, $cx, $cy, $w, $h, $s, $e, $color) | 畫弧線 (角度 0-360) |
imagepolygon($im, $points, $num, $color) | 畫多邊形 |
imagefilledpolygon($im, $points, $num, $color) | 畫實心多邊形 |
4. 文字繪製
| 函數 | 說明 |
imagestring($im, $font, $x, $y, $str, $color) | 內建字體 (1-5) 畫橫向文字 |
imagestringup($im, $font, $x, $y, $str, $color) | 內建字體畫直向文字 |
imagettftext($im, $size, $angle, $x, $y, $color, $fontfile, $text) | **TrueType 字體**繪製 (支援中文、旋轉、抗鋸齒) |
imagettfbbox($size, $angle, $fontfile, $text) | 計算 TTF 文字邊界框 (用於置中對齊) |
5. 圖片複製、縮放、合成
| 函數 | 說明 |
imagecopy($dst, $src, $dx, $dy, $sx, $sy, $sw, $sh) | 複製區塊 |
imagecopyresized($dst, $src, $dx, $dy, $sx, $sy, $dw, $dh, $sw, $sh) | 複製並縮放 (低質量) |
imagecopyresampled($dst, $src, $dx, $dy, $sx, $sy, $dw, $dh, $sw, $sh) | **高質量重採樣縮放** (推薦) |
imagecopymerge($dst, $src, $dx, $dy, $sx, $sy, $sw, $sh, $pct) | 帶透明度合成 (水印用) |
imagecopymergegray($dst, $src, $dx, $dy, $sx, $sy, $sw, $sh, $pct) | 灰度合成 |
6. 輸出與銷毀
| 函數 | 說明 |
imagepng|jpeg|gif|webp|wbmp($im, $file?, $quality?) | 輸出到檔案或瀏覽器 |
imagedestroy($im) | 釋放記憶體 (重要!) |
實戰範例:驗證碼生成器
<?php
session_start();
$width = 120; $height = 40;
$im = imagecreatetruecolor($width, $height);
// 背景
$bg = imagecolorallocate($im, 240, 240, 240);
imagefilledrectangle($im, 0, 0, $width, $height, $bg);
// 干擾線
for ($i = 0; $i < 5; $i++) {
$lineColor = imagecolorallocate($im, rand(150, 200), rand(150, 200), rand(150, 200));
imageline($im, 0, rand(0, $height), $width, rand(0, $height), $lineColor);
}
// 干擾點
for ($i = 0; $i < 50; $i++) {
$dotColor = imagecolorallocate($im, rand(100, 200), rand(100, 200), rand(100, 200));
imagesetpixel($im, rand(0, $width), rand(0, $height), $dotColor);
}
// 文字
$code = '';
$font = __DIR__ . '/fonts/arial.ttf'; // 需自備 TTF
for ($i = 0; $i < 4; $i++) {
$char = substr('ABCDEFGHJKLMNPQRSTUVWXYZ23456789', rand(0, 31), 1);
$code .= $char;
$x = 20 + $i * 24;
$y = 30;
$angle = rand(-15, 15);
$color = imagecolorallocate($im, rand(0, 100), rand(0, 100), rand(0, 100));
imagettftext($im, 18, $angle, $x, $y, $color, $font, $char);
}
$_SESSION['captcha'] = strtolower($code);
header('Content-Type: image/png');
imagepng($im);
imagedestroy($im);
?>
實戰範例:圖片縮圖 + 水印
<?php
function thumbWithWatermark(string $src, string $dest, int $maxW = 800, int $maxH = 600, string $wmText = '© MySite'): void {
list($ow, $oh, $type) = getimagesize($src);
$create = ['imagecreatefrompng', 'imagecreatefromjpeg', 'imagecreatefromgif', 'imagecreatefromwebp'][$type - 1] ?? null;
if (!$create) throw new Exception('Unsupported format');
$srcIm = $create($src);
$ratio = min($maxW / $ow, $maxH / $oh, 1); // 不放大
$nw = (int)($ow * $ratio);
$nh = (int)($oh * $ratio);
$dstIm = imagecreatetruecolor($nw, $nh);
imagecopyresampled($dstIm, $srcIm, 0, 0, 0, 0, $nw, $nh, $ow, $oh);
// 水印
$font = __DIR__ . '/fonts/msjh.ttc'; // 微軟正黑體
$wmColor = imagecolorallocatealpha($dstIm, 255, 255, 255, 60); // 半透明白
$box = imagettfbbox(16, 0, $font, $wmText);
$tw = $box[2] - $box[0];
$th = $box[5] - $box[3];
$x = $nw - $tw - 10;
$y = $nh - $th - 10;
imagettftext($dstIm, 16, 0, $x, $y, $wmColor, $font, $wmText);
// 輸出
imagejpeg($dstIm, $dest, 85);
imagedestroy($srcIm);
imagedestroy($dstIm);
}
?>
效能與記憶體優化
- 大圖處理前調大
memory_limit (如 256M/512M)
- 及時
imagedestroy() 釋放資源,避免 FPM 進程記憶體洩漏
- 批量處理考慮 CLI 模式 +
pcntl_fork 平行化
- 純縮圖場景可考慮
Imagick (多線程、格式支援更廣)