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

PHP 獲取驗證碼圖片並本地化:GD 庫實作與多格式支援

     編輯:PHP 相關知識

自動化測試、爬蟲專案常需獲取驗證碼圖片進行識別或人工標註。本文示範使用 GD 庫獲取遠端驗證碼圖片並統一輸出為 PNG,支援 JPEG、PNG、GIF 三種格式。

核心實作:格式自動偵測與轉換

<?php
header('Content-Type: image/png');
set_time_limit(0);

$url = $_GET['url'] ?? 'https://example.com/captcha.jpg';
if (empty($url)) {
    die('缺少 url 參數');
}

// 1. 取得圖片資訊(含類型)
$imgInfo = @getimagesize($url);
if (!$imgInfo) {
    die('無法讀取圖片資訊');
}

$width = $imgInfo[0];
$height = $imgInfo[1];
$mimeType = $imgInfo['mime'] ?? '';

// 2. 根據 MIME 類型建立圖片資源
switch ($mimeType) {
    case 'image/jpeg':
        $source = @imagecreatefromjpeg($url);
        break;
    case 'image/png':
        $source = @imagecreatefrompng($url);
        break;
    case 'image/gif':
        $source = @imagecreatefromgif($url);
        break;
    default:
        die("不支援的圖片格式: $mimeType");
}

if (!$source) {
    die('建立圖片資源失敗');
}

// 3. 建立真彩色畫布並複製
$canvas = imagecreatetruecolor($width, $height);

// 保留透明度(PNG/GIF)
if ($mimeType === 'image/png' || $mimeType === 'image/gif') {
    imagealphablending($canvas, false);
    imagesavealpha($canvas, true);
    $transparent = imagecolorallocatealpha($canvas, 255, 255, 255, 127);
    imagefill($canvas, 0, 0, $transparent);
} else {
    // JPEG 白底
    $white = imagecolorallocate($canvas, 255, 255, 255);
    imagefill($canvas, 0, 0, $white);
}

imagecopy($canvas, $source, 0, 0, 0, 0, $width, $height);
imagedestroy($source);

// 4. 輸出 PNG
imagepng($canvas);
imagedestroy($canvas);
?>

進階版:exif_imagetype 更可靠的格式偵測

<?php
function getCaptchaImage(string $url): ?string {
    // 使用 exif_imagetype 不需載入完整圖片即可判斷類型
    $type = @exif_imagetype($url);
    if (!$type) return null;

    $createFunc = match ($type) {
        IMAGETYPE_JPEG => 'imagecreatefromjpeg',
        IMAGETYPE_PNG  => 'imagecreatefrompng',
        IMAGETYPE_GIF  => 'imagecreatefromgif',
        IMAGETYPE_WEBP => 'imagecreatefromwebp', // PHP 8.1+
        IMAGETYPE_BMP  => 'imagecreatefrombmp',  // PHP 7.2+
        default => null,
    };

    if (!$createFunc) return null;

    $source = $createFunc($url);
    if (!$source) return null;

    $width = imagesx($source);
    $height = imagesy($source);

    $canvas = imagecreatetruecolor($width, $height);
    
    // 統一處理透明度
    if (in_array($type, [IMAGETYPE_PNG, IMAGETYPE_GIF, IMAGETYPE_WEBP])) {
        imagealphablending($canvas, false);
        imagesavealpha($canvas, true);
    }

    imagecopy($canvas, $source, 0, 0, 0, 0, $width, $height);
    imagedestroy($source);

    // 輸出到字串而非直接輸出
    ob_start();
    imagepng($canvas);
    $pngData = ob_get_clean();
    imagedestroy($canvas);

    return $pngData;
}

// 使用:儲存檔案或直接輸出
$png = getCaptchaImage('https://example.com/captcha.jpg');
if ($png) {
    file_put_contents('captcha_' . time() . '.png', $png);
}
?>

驗證碼識別整合建議

階段工具/方法
圖片預處理灰階、二值化、去噪、字符分割
傳統 OCRTesseract (需訓練字體)、gocr
深度學習CNN + CTC (CRNN)、Transformer-based
現成服務Google Vision、AWS Rekognition、超級鷹等打碼平台

法律與道德邊界

⚠️ 重要提醒
自動化繞過驗證碼可能違反網站服務條款、計算機犯罪法或反爬蟲法規。僅用於:
1. 自家系統自動化測試
2. 已授權的安全性測試
3. 學術研究(遵守 robots.txt)
嚴禁用於惡意註冊、暴力破解、資料竊取等非法用途。

常見問題排查

  • imagecreatefromjpeg 失敗:URL 非直接圖片連結(可能是 HTML 頁面),需先分析網頁結構
  • GD 不支援 WebP:PHP < 8.1 需用 imagecreatefromstring(file_get_contents($url)) 讓 GD 自動偵測
  • 記憶體不足:大圖片處理前先 ini_set('memory_limit', '256M')
  • Session 不一致:獲取驗證碼與提交表單需共用 Cookie Jar
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved