矩形是圖形學中最基礎的構建塊,從簡單的邊框、背景塊、進度條、表格格線到複雜的 UI 組件、驗證碼干擾線,無不依賴矩形繪製。PHP GD 提供了兩大核心函數:imagerectangle() (空心邊框) 與 imagefilledrectangle() (實心填滿)。本文將深入解析參數幾何意義、座標陷阱、進階用法與實戰模式。
// 空心矩形框 (1像素寬邊框)
bool imagerectangle (
resource $image,
int $x1, int $y1, // **左上角** 頂點座標
int $x2, int $y2, // **右下角** 頂點座標
int $color // 邊框顏色
);
// 實心填滿矩形
bool imagefilledrectangle (
resource $image,
int $x1, int $y1, // **左上角** 頂點座標
int $x2, int $y2, // **右下角** 頂點座標
int $color // 填滿顏色
);
($x1, $y1) **必須**為左上角,($x2, $y2) **必須**為右下角。即 $x1 < $x2 且 $y1 < $y2。若順序顛倒,函數**不報錯但不繪製任何內容** (返回 false)。$x2 - $x1 + 1,高度 = $y2 - $y1 + 1。<?php
// 1. 建立畫布 400x300
$im = imagecreatetruecolor(400, 300);
$white = imagecolorallocate($im, 255, 255, 255);
$black = imagecolorallocate($im, 0, 0, 0);
$red = imagecolorallocate($im, 255, 0, 0);
$blue = imagecolorallocate($im, 0, 0, 255);
$green = imagecolorallocate($im, 0, 200, 0);
imagefill($im, 0, 0, $white);
// 2. 空心紅框:左上(50,50) 右下(350,250)
imagerectangle($im, 50, 50, 350, 250, $red);
// 3. 實心藍塊:左上(100,100) 右下(200,180)
imagefilledrectangle($im, 100, 100, 200, 180, $blue);
// 4. 實心綠條 (進度條雛形):左上(50, 260) 右下(250, 280)
imagefilledrectangle($im, 50, 260, 250, 280, $green);
// 5. 輸出
header('Content-Type: image/png');
imagepng($im);
imagedestroy($im);
?>
核心思路:**四個圓角扇形 + 四條直線 + 中心矩形** 組合。或使用 imagefilledarc 畫四個 90° 扇形填角,再用 imagefilledrectangle 填中間。
function imagefilledroundedrect($im, $x1, $y1, $x2, $y2, $radius, $color) {
// 參數檢查
if ($radius < 1) return imagefilledrectangle($im, $x1, $y1, $x2, $y2, $color);
$d = $radius * 2;
// 1. 四個角:填滿扇形 (PIE 模式)
imagefilledarc($im, $x1+$radius, $y1+$radius, $d, $d, 180, 270, $color, IMG_ARC_PIE); // 左上
imagefilledarc($im, $x2-$radius, $y1+$radius, $d, $d, 270, 360, $color, IMG_ARC_PIE); // 右上
imagefilledarc($im, $x2-$radius, $y2-$radius, $d, $d, 0, 90, $color, IMG_ARC_PIE); // 右下
imagefilledarc($im, $x1+$radius, $y2-$radius, $d, $d, 90, 180, $color, IMG_ARC_PIE); // 左下
// 2. 中間橫向矩形
imagefilledrectangle($im, $x1+$radius, $y1, $x2-$radius, $y2, $color);
// 3. 中間縱向矩形 (覆蓋角落已填區域無妨)
imagefilledrectangle($im, $x1, $y1+$radius, $x2, $y2-$radius, $color);
}
function imagerectangle_thick($im, $x1, $y1, $x2, $y2, $color, $thickness = 2) {
for ($i = 0; $i < $thickness; $i++) {
imagerectangle($im, $x1-$i, $y1-$i, $x2+$i, $y2+$i, $color);
}
}
// 或用 filledrectangle 畫四條粗條組合 (效能更好)
function imagerectangle_thick_fast($im, $x1, $y1, $x2, $y2, $color, $thickness = 3) {
// 上邊
imagefilledrectangle($im, $x1, $y1, $x2, $y1+$thickness-1, $color);
// 下邊
imagefilledrectangle($im, $x1, $y2-$thickness+1, $x2, $y2, $color);
// 左邊
imagefilledrectangle($im, $x1, $y1, $x1+$thickness-1, $y2, $color);
// 右邊
imagefilledrectangle($im, $x2-$thickness+1, $y1, $x2, $y2, $color);
}
function imagefilledrectangle_gradient_v($im, $x1, $y1, $x2, $y2, $startColor, $endColor) {
$height = $y2 - $y1 + 1;
$r1 = ($startColor >> 16) & 0xFF; $g1 = ($startColor >> 8) & 0xFF; $b1 = $startColor & 0xFF;
$r2 = ($endColor >> 16) & 0xFF; $g2 = ($endColor >> 8) & 0xFF; $b2 = $endColor & 0xFF;
for ($y = 0; $y < $height; $y++) {
$ratio = $y / max(1, $height - 1);
$r = (int)($r1 + ($r2 - $r1) * $ratio);
$g = (int)($g1 + ($g2 - $g1) * $ratio);
$b = (int)($b1 + ($b2 - $b1) * $ratio);
$color = imagecolorallocate($im, $r, $g, $b);
imageline($im, $x1, $y1+$y, $x2, $y1+$y, $color); // 逐行畫線
}
}
// 使用:imagefilledrectangle_gradient_v($im, 50,50, 350,250, 0x3498db, 0x2ecc71);
// 必須啟用 Alpha 混合
imagealphablending($im, true);
imagesavealpha($im, true);
// 分配半透明顏色 (Alpha: 0 不透明 - 127 完全透明)
$rgba = imagecolorallocatealpha($im, 0, 0, 0, 80); // 黑色 60% 不透明度
imagefilledrectangle($im, 0, 0, 399, 299, $rgba); // 全屏半透明遮罩
| 場景 | 核心函數組合 | 關鍵點 |
|---|---|---|
| 進度條 | 背景框 + 實心填滿寬度動態計算 | 寬度 = 總寬 * 進度%; 圓角美化 |
| 表格/網格 | 迴畫橫線 + 豎線 | 座標計算: $x = $start + $col * $cellW |
| 驗證碼干擾 | 隨機位置/顏色/大小 實心/空心矩形 | 迴圈 50-100 次; 避免遮蓋文字 |
| 圖片裁剪區標註 | 空心矩形 + 拖拽手柄 (小實心方塊) | 前端 JS 交互,後端接收座標裁剪 |
| 文字背景塊 | 計算文字 bbox → 留 padding → 畫實心矩形 → 畫文字 | imagettfbbox 獲取寬高 |
| 半透明水印條 | 底部 imagefilledrectangle (rgba) + imagettftext | imagecolorallocatealpha + alphablending |
$x1 > $x2 或 $y1 > $y2 → **無輸出,無報錯**。防禦性編程:list($x1,$x2) = [$x1,$x2]; sort($x1,$x2); 或封裝函數內部排序。imagesx($im)-1 或 imagesy($im)-1 → 截斷繪製,不報錯。建議 clamp($x, 0, $w-1)。imagecolorallocate 返回 false。真彩色模式 imagecreatetruecolor 無此限制。**永遠用 truecolor**。imagealphablending($im, true) 和 imagesavealpha($im, true)。$x2 - $x1 + 1。若需精確 100px 寬,$x2 = $x1 + 99。imagerectangle() 與 imagefilledrectangle() 是 GD 繪圖的**原子操作**。掌握其**左上/右下頂點座標制**、**端點包含特性**、**真彩色模式下的無限顏色與 Alpha 支援**,再結合迴圈、條件判斷、幾何計算,即可構建出進度條、表格、圓角卡片、漸變背景、半透明遮罩、裁剪框等所有矩形基礎 UI 元件。記住核心口訣:左上右下、真彩色、含端點、Alpha全開。