首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP GD 庫圖形處理完全指南:從基礎繪圖到驗證碼生成

     編輯:PHP 相關知識

掌握 PHP GD 庫:圖像創建、文字繪製與驗證碼實戰

GD 庫是 PHP 內置的強大圖形處理擴展,支持 GIF、PNG、JPEG、WBMP、XBM 等主流格式,廣泛應用於圖表生成、圖片水印、驗證碼、縮略圖等場景。本文將從環境配置、畫布創建、中文繪製到完整驗證碼系統,系統講解 GD 庫核心用法與最佳實踐。

一、環境準備:啟用 GD 擴展

PHP 5.3+ 預裝 GD 庫,但需在 php.ini 中啟用:

; 移除分號啟用擴展
extension=php_gd2.dll

修改後重啟 Apache/Nginx。驗證安裝:執行 php -m | grep gd 或查看 phpinfo() 輸出中的 GD 信息。確保顯示 FreeType Support: enabled 以支持 TrueType 字體渲染中文。

二、核心概念:畫布與座標系統

所有繪圖操作始於 畫布創建:

  • imagecreate($width, $height):創建基於調色板的圖像(舊版,色彩有限)
  • imagecreatetruecolor($width, $height):創建真彩色圖像(推薦,支持 1670 萬色)

座標系統:原點 (0,0) 位於左上角,X 軸向右,Y 軸向下。顏色通過 imagecolorallocate($image, $r, $g, $b) 分配,返回顏色標識符。

三、基礎繪圖實戰:創建帶背景色的畫布

<?php
header('Content-Type: image/gif');
$im = imagecreatetruecolor(200, 60); // 創建真彩色畫布
$bgColor = imagecolorallocate($im, 225, 66, 159); // 分配背景色(粉紅)
imagefill($im, 0, 0, $bgColor); // 填充背景
imagegif($im); // 輸出 GIF
imagedestroy($im); // 釋放資源
?>

關鍵點:imagefill 填充畫布,imagedestroy 必須調用防止內存洩漏。

四、中文繪製難點與解決方案

GD 庫原生 imagestring 僅支持 ASCII 字符。繪製中文需:

  1. 使用 TrueType 字體(.ttf/.ttc),如微軟雅黑、思源黑體
  2. 字符編碼為 UTF-8,若源文件非 UTF-8 需 iconv 轉換
  3. 調用 imagettftext() 繪製
<?php
header('Content-Type: image/jpeg');
$im = imagecreatefromjpeg('photo.jpg'); // 載入底圖
$textColor = imagecolorallocate($im, 56, 73, 136); // 藍色文字
$fontPath = 'C:/Windows/Fonts/msyh.ttc'; // 微軟雅黑路徑
$text = iconv('GBK', 'UTF-8', '這是一個測試'); // 編碼轉換
imagettftext($im, 24, 0, 50, 50, $textColor, $fontPath, $text);
imagejpeg($im);
imagedestroy($im);
?>

參數詳解:字體大小 24、角度 0、座標 (50,50)、字體路徑、UTF-8 文本。

五、完整驗證碼系統實現

1. 生成端 check_code.php

<?php
session_start();
header('Content-Type: image/png');
$width = 100; $height = 36;
$image = imagecreatetruecolor($width, $height);
$bg = imagecolorallocate($image, 240, 240, 240);
imagefill($image, 0, 0, $bg);

// 生成 4 位隨機字符(數字+大小寫字母)
$chars = '0123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz';
$code = '';
for ($i = 0; $i < 4; $i++) {
    $code .= $chars[mt_rand(0, strlen($chars)-1)];
}
$_SESSION['captcha_code'] = strtolower($code); // 存儲小寫便於驗證

// 繪製干擾線
for ($i = 0; $i < 5; $i++) {
    $lineColor = imagecolorallocate($image, mt_rand(100,200), mt_rand(100,200), mt_rand(100,200));
    imageline($image, mt_rand(0,$width), mt_rand(0,$height), mt_rand(0,$width), mt_rand(0,$height), $lineColor);
}

// 繪製干擾點
for ($i = 0; $i < 50; $i++) {
    $dotColor = imagecolorallocate($image, mt_rand(0,255), mt_rand(0,255), mt_rand(0,255));
    imagesetpixel($image, mt_rand(0,$width), mt_rand(0,$height), $dotColor);
}

// 繪製驗證碼字符
$font = __DIR__ . '/fonts/arial.ttf';
for ($i = 0; $i < 4; $i++) {
    $charColor = imagecolorallocate($image, mt_rand(0,100), mt_rand(0,100), mt_rand(0,100));
    $x = 15 + $i * 22 + mt_rand(-2, 2);
    $y = 26 + mt_rand(-2, 2);
    imagettftext($image, 20, mt_rand(-15, 15), $x, $y, $charColor, $font, $code[$i]);
}

imagepng($image);
imagedestroy($image);
?>

2. 驗證端 login.php

<?php
session_start();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $input = strtolower(trim($_POST['captcha']));
    if (empty($input)) {
        $msg = '請輸入驗證碼';
    } elseif ($input === $_SESSION['captcha_code']) {
        $msg = '驗證通過,登錄成功!';
        unset($_SESSION['captcha_code']); // 一次性使用
    } else {
        $msg = '驗證碼錯誤';
    }
}
?>
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>登錄驗證</title></head><body>
<form method="post">
    用戶名:<input name="username" required><br>
    密碼:<input name="password" type="password" required><br>
    驗證碼:<input name="captcha" maxlength="4" required>
    <img src="check_code.php" alt="點擊刷新" onclick="this.src='check_code.php?'+Math.random()" style="cursor:pointer;vertical-align:middle"><br>
    <button type="submit">登錄</button>
    <p style="color:red"><?php echo isset($msg) ? $msg : ''; ?></p>
</form>
</body></html>

六、進階技巧與常見問題

  • 抗鋸齒:imageantialias($image, true) 開啟線條抗鋸齒(僅對線條有效)
  • 透明背景:imagecolortransparent($image, $color) 設置透明色
  • 圖片縮放:imagecopyresampled() 高質量縮放,保持清晰度
  • 內存管理:大圖處理後務必 imagedestroy(),長時間運行腳本需監控內存
  • 字體路徑:Linux 下字體通常在 /usr/share/fonts/,建議將字體文件隨項目部署,使用相對路徑

七、總結

GD 庫雖非專業圖形處理庫(如 ImageMagick),但無需外部依賴、性能優異、API 成熟,完全滿足 Web 開發中 90% 的圖像處理需求。掌握畫布操作、色彩管理、字體渲染、干擾元素生成等核心技能,配合 Session 驗證機制,即可構建安全可靠的驗證碼系統。進階場景可結合 imagick 擴展實現更複雜的圖像合成、格式轉換等功能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved