環境需求
- PHP 編譯時加入
--with-gd(PHP 7.4 以前)或 --enable-gd(PHP 8.0+)。
- 系統需安裝 libgd、libpng、libjpeg、freetype 開發套件。
- Windows 環境預設已內建 GD,確認
php.ini 中 extension=gd 已啟用。
核心函數分類速查
1. 畫布建立與載入
| 函數 | 說明 |
imagecreatetruecolor($w, $h) | 建立真彩色畫布(推薦,支援 24-bit 色彩) |
imagecreate($w, $h) | 建立調色盤模式畫布(舊版,僅 256 色) |
imagecreatefromjpeg/png/gif/webp($file) | 從檔案載入圖片資源 |
imagedestroy($img) | 釋放圖片資源記憶體 |
2. 顏色管理
| 函數 | 說明 |
imagecolorallocate($img, $r, $g, $b) | 分配顏色(真彩色模式直接使用 RGB) |
imagecolorallocatealpha($img, $r, $g, $b, $alpha) | 分配半透明顏色(0 不透明 ~ 127 完全透明) |
imagecolortransparent($img, $color) | 設定透明色 |
3. 繪圖基礎圖形
| 函數 | 參數說明 |
imagesetpixel($img, $x, $y, $color) | 畫單一像素 |
imageline($img, $x1, $y1, $x2, $y2, $color) | 畫直線 |
| imagerectangle($img, $x1, $y1, $x2, $y2, $color) | 畫矩形框線 |
imagefilledrectangle($img, $x1, $y1, $x2, $y2, $color) | 畫實心矩形 |
imageellipse($img, $cx, $cy, $w, $h, $color) | 畫橢圓/圓框線 |
imagefilledellipse($img, $cx, $cy, $w, $h, $color) | 畫實心橢圓/圓 |
imagearc($img, $cx, $cy, $w, $h, $start, $end, $color) | 畫橢圓弧 |
imagepolygon($img, $points, $num, $color) | 畫多邊形框線($points 為 [x1,y1,x2,y2...]) |
imagefilledpolygon($img, $points, $num, $color) | 畫實心多邊形 |
4. 文字繪製(需 FreeType)
| 函數 | 說明 |
imagettftext($img, $size, $angle, $x, $y, $color, $fontfile, $text) | TrueType 字體繪製文字(支援中文、旋轉、抗鋸齒) |
imagettfbbox($size, $angle, $fontfile, $text) | 計算文字邊界框,用於置中對齊 |
5. 輸出與進階
| 函數 | 說明 |
imagepng/jpeg/gif/webp($img, $file=null, $quality) | 輸出圖片($file=null 直接輸出瀏覽器) |
imagecopyresampled($dst, $src, $dx, $dy, $sx, $sy, $dw, $dh, $sw, $sh) | 高品質縮放複製(縮圖必備) |
imagefilter($img, IMG_FILTER_*) | 濾鏡效果(灰階、銳化、高斯模糊等) |
實戰範例:中文驗證碼生成器
<?php
session_start();
$width = 130; $height = 45;
$img = imagecreatetruecolor($width, $height);
// 背景漸層
$bgStart = imagecolorallocate($img, 230, 240, 255);
$bgEnd = imagecolorallocate($img, 200, 220, 245);
for ($y = 0; $y < $height; $y++) {
$r = 230 + (200-230) * $y / $height;
$g = 240 + (220-240) * $y / $height;
$b = 255 + (245-255) * $y / $height;
$color = imagecolorallocate($img, $r, $g, $b);
imageline($img, 0, $y, $width, $y, $color);
}
// 干擾線
for ($i = 0; $i < 5; $i++) {
$lineColor = imagecolorallocatealpha($img, rand(100,200), rand(100,200), rand(100,200), 60);
imageline($img, rand(0,$width), rand(0,$height), rand(0,$width), rand(0,$height), $lineColor);
}
// 干擾點
for ($i = 0; $i < 80; $i++) {
$dotColor = imagecolorallocatealpha($img, rand(0,150), rand(0,150), rand(0,150), 40);
imagesetpixel($img, rand(0,$width), rand(0,$height), $dotColor);
}
// 產生 4 碼驗證碼(數字+大寫字母)
$chars = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ';
$code = '';
for ($i = 0; $i < 4; $i++) $code .= $chars[rand(0, strlen($chars)-1)];
$_SESSION['captcha'] = $code;
// 字體檔案路徑(需自行準備 .ttf)
$font = __DIR__ . '/fonts/NotoSansTC-Regular.otf';
$textColor = imagecolorallocate($img, 40, 60, 100);
// 逐字繪製,隨機旋轉、位移
$x = 15;
for ($i = 0; $i < 4; $i++) {
$angle = rand(-15, 15);
$y = rand(30, 38);
imagettftext($img, 22, $angle, $x, $y, $textColor, $font, $code[$i]);
$x += 28;
}
header('Content-Type: image/png');
imagepng($img);
imagedestroy($img);
?>
實戰範例:縮圖自動生成(保持比例)
<?php
function createThumbnail(string $srcPath, string $dstPath, int $maxW, int $maxH, int $quality = 85): bool {
$info = getimagesize($srcPath);
if (!$info) return false;
[$srcW, $srcH, $type] = $info;
$createFunc = [
IMAGETYPE_JPEG => 'imagecreatefromjpeg',
IMAGETYPE_PNG => 'imagecreatefrompng',
IMAGETYPE_GIF => 'imagecreatefromgif',
IMAGETYPE_WEBP => 'imagecreatefromwebp',
][$type] ?? null;
if (!$createFunc) return false;
$srcImg = $createFunc($srcPath);
if (!$srcImg) return false;
// 計算縮放比例
$ratio = min($maxW / $srcW, $maxH / $srcH);
if ($ratio >= 1) { // 原圖較小,直接複製
copy($srcPath, $dstPath);
imagedestroy($srcImg);
return true;
}
$dstW = (int)($srcW * $ratio);
$dstH = (int)($srcH * $ratio);
$dstImg = imagecreatetruecolor($dstW, $dstH);
// PNG/GIF 保持透明
if ($type === IMAGETYPE_PNG || $type === IMAGETYPE_GIF) {
imagealphablending($dstImg, false);
imagesavealpha($dstImg, true);
$transparent = imagecolorallocatealpha($dstImg, 255, 255, 255, 127);
imagefilledrectangle($dstImg, 0, 0, $dstW, $dstH, $transparent);
}
imagecopyresampled($dstImg, $srcImg, 0, 0, 0, 0, $dstW, $dstH, $srcW, $srcH);
$outputFunc = [
IMAGETYPE_JPEG => fn() => imagejpeg($dstImg, $dstPath, $quality),
IMAGETYPE_PNG => fn() => imagepng($dstImg, $dstPath, 9),
IMAGETYPE_GIF => fn() => imagegif($dstImg, $dstPath),
IMAGETYPE_WEBP => fn() => imagewebp($dstImg, $dstPath, $quality),
][$type];
$result = $outputFunc();
imagedestroy($srcImg);
imagedestroy($dstImg);
return $result;
}
// 使用
createThumbnail('uploads/photo.jpg', 'uploads/thumb_photo.jpg', 300, 200);
?>
常見問題與除錯
- 中文顯示方框/亂碼:確認字體檔路徑正確、支援中文、PHP 編譯含 FreeType(
php -i | grep -i freetype)。
- 記憶體耗盡:大圖處理前調大
memory_limit,處理完立即 imagedestroy()。
- 輸出前有空白字元:確保
header() 前無任何輸出(含 BOM、空行),建議純 PHP 檔案省略結尾 ?>。
- 透明背景變黑:PNG/GIF 縮圖需開啟
imagesavealpha 並分配透明色填充畫布。
結語
GD 函數庫是 PHP 伺服端圖形處理的基石,掌握畫布建立、顏色管理、繪圖、文字渲染、縮圖輸出等核心流程,即可實現驗證碼、圖表、水印、縮圖等常見需求。現代專案亦可考慮 ImageMagick (imagick 擴展) 以獲得更強大的向量圖形、PDF 渲染、濾鏡效能。