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

PHP GD 圖形函數完整指南:動態生成圖片與驗證碼實戰

     編輯:PHP 相關知識

環境需求

  • 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 渲染、濾鏡效能。

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