自動化測試、爬蟲專案常需獲取驗證碼圖片進行識別或人工標註。本文示範使用 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);
?>
<?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);
}
?>
| 階段 | 工具/方法 |
|---|---|
| 圖片預處理 | 灰階、二值化、去噪、字符分割 |
| 傳統 OCR | Tesseract (需訓練字體)、gocr |
| 深度學習 | CNN + CTC (CRNN)、Transformer-based |
| 現成服務 | Google Vision、AWS Rekognition、超級鷹等打碼平台 |
imagecreatefromstring(file_get_contents($url)) 讓 GD 自動偵測ini_set('memory_limit', '256M')