在 OA 系統、電子合同、證書生成等場景中,程序化繪製帶有中文繞圓排版的圓形印章是一項硬核需求。本文深度解析兩種主流實現方案:面向對象封裝類(方法一)與過程式腳本(方法二),並對比其在字符排版、幾何計算、性能上的異同。
CircleSeal 類 —— 企業級封裝方案該方案將印章參數(半徑、邊框、字體、顏色等)全部屬性化,核心邏輯拆分為獨立私有方法,結構清晰,易於擴展維護。
印章文字沿圓周均勻分佈,關鍵在於計算每個字符的圓心角(位置角)與字符旋轉角(切線角):
<?php
// 簡化版核心邏輯
$charRadius = $sealRadius - $rimWidth - $fontSize; // 文字軌道半徑
$leng = mb_strlen($text, 'utf-8');
$avgAngle = 360 / $maxChars; // 平均角度間隔
for ($i = 0; $i < $leng; $i++) {
// 位置角:字符中心在圓周上的極角
$posAngle = 630 + $charAngle + $avgAngle * ($i - $leng/2) + $spacing * ($i-1);
// 旋轉角:字符基線與切線夾角,使文字沿圓弧自然彎曲
$rotAngle = 720 - $charAngle + $avgAngle * ($leng - 2*$i - 1)/2 + $spacing * (1-$i);
$x = $centerX + $charRadius * cos(deg2rad($posAngle));
$y = $centerY + $charRadius * sin(deg2rad($posAngle));
imagettftext($img, $fontSize, $rotAngle, $x, $y, $color, $font, $char);
}
?>
關鍵點:630°/720° 等魔數實為 270°/360° 的 360° 偏移,配合 deg2rad 換算,確保文字從正上方(12 點鐘方向)開始順時針排布。
使用 imagefilledpolygon 繪製正五角星,通過外接圓半徑 R 內切圓半徑 r = R * 0.382(黃金分割比)計算 10 個頂點坐標:
<?php
$points = [];
for ($i = 0; $i < 5; $i++) {
// 外頂點
$points[] = $cx + $R * cos(2*M_PI/5*$i - deg2rad($ang_out));
$points[] = $cy + $R * sin(2*M_PI/5*$i - deg2rad($ang_out));
// 內凹點
$points[] = $cx + $r * cos(2*M_PI/5*($i+1) - deg2rad($ang_in));
$points[] = $cy + $r * sin(2*M_PI/5*($i+1) - deg2rad($ang_in));
}
imagefilledpolygon($img, $points, 10, $color);
?>
無類封裝,邏輯線性執行,適合一次性腳本或嵌入式調用。其字符排版邏輯採用「雙向展開」策略:
$j = floor($count/2)。| 難點 | 解決方案 |
|---|---|
| 中文編碼亂碼 | 統一使用 mb_convert_encoding($str, 'UTF-8', 'GBK') 轉碼,確保 imagettftext 接收 UTF-8。 |
| 字體文件路徑 | 生產環境務必使用絕對路徑 __DIR__ . '/fonts/simkai.ttf',避免相對路徑失效。 |
| GD 庫未啟用 | 檢查 phpinfo() 中 GD 支持,安裝 php-gd 擴展並開啟 FreeType。 |
| 透明背景 | 使用 imagecreatetruecolor + imagecolorallocatealpha + imagesavealpha 輸出 PNG 透明通道。 |
md5($params) 命名緩存 PNG 文件,避免重複繪製消耗 CPU。imagettftext 渲染速度。Imagick 或 SVG + ImageMagick 轉 PNG,獲得更優的抗鋸齒與向量縮放能力。方法一適合構建通用印章服務組件,方法二適合快速原型驗證。掌握「極坐標換算直角坐標 + 字符旋轉角計算」這一核心數學模型,即可舉一反三實現任意曲線文字排版(如拱形、波浪形)。