| 函數 | 原型 | 說明 |
imagegrabscreen() | resource imagegrabscreen(): GdImage|false | 截取整個螢幕(所有顯示器合成畫面)。 |
imagegrabwindow() | resource imagegrabwindow(int $window_handle, int $client_area = 0): GdImage|false | 截取指定視窗句柄(HWND)畫面。$client_area=1 僅客戶區(不含標題列/邊框)。 |
基本範例
1. 截取全螢幕並存為 PNG
<?php
$im = imagegrabscreen();
if ($im) {
imagepng($im, 'screenshot.png');
imagedestroy($im);
echo "截圖成功:screenshot.png";
} else {
echo "截圖失敗,請檢查環境與權限。";
}
?>
2. 截取 IE 視窗(需 COM 元件)
<?php
// 建立 IE 實例
$browser = new COM("InternetExplorer.Application");
$handle = $browser->HWND;
$browser->Visible = true;
$browser->Navigate("https://www.example.com");
// 等待載入完成
while ($browser->Busy) {
com_message_pump(4000);
}
$im = imagegrabwindow($handle, 0); // 0 = 整個視窗含標題列
$browser->Quit();
if ($im) {
imagepng($im, 'ie_window.png');
imagedestroy($im);
}
?>
3. 截取 IE 客戶區(僅網頁內容)
$im = imagegrabwindow($handle, 1); // 1 = 僅客戶區
4. IE 全螢幕模式截圖
$browser->FullScreen = true;
$browser->Navigate("https://www.example.com");
while ($browser->Busy) com_message_pump(4000);
$im = imagegrabwindow($handle, 0);
常見問題與解決方案
問題一:輸出圖片全黑
原因:Apache 運行於 Session 0(非互動式),無法存取桌面視窗站台。
解決:
- 開啟「服務」管理員(
services.msc)。
- 找到 Apache 服務(如
Apache2.4),右鍵 → 內容 → 登入。
- 勾選 「允許服務與桌面互動」。
- 重啟 Apache 服務。
若使用整合包(XAMPP/WAMP),請改以 CLI 模式執行腳本:php screenshot.php。
問題二:COM 元件找不到 / Class 'COM' not found
解決:確認 php.ini 啟用 extension=php_com_dotnet.dll(PHP 7.4+ 內建,舊版需單獨安裝)。
問題三:截圖解析度不符 / 縮放模糊
Windows DPI 縮放(125%、150%)會影響 GDI 捕獲尺寸。建議:
- 在 PHP 腳本啟動前呼叫
SetProcessDPIAware()(需透過 FFI 或 COM 呼叫 user32.dll)。
- 或於系統設定將縮放設為 100%。
進階應用:定時監控網頁變化
<?php
// cron 每 5 分鐘執行一次
$url = 'https://target-site.com/dashboard';
$hashFile = 'last_hash.txt';
$browser = new COM("InternetExplorer.Application");
$browser->Visible = false; // 無頭模式
$browser->Navigate($url);
while ($browser->Busy) com_message_pump(4000);
$handle = $browser->HWND;
$im = imagegrabwindow($handle, 1);
$browser->Quit();
if ($im) {
// 計算圖片感知雜湊
$currentHash = perceptual_hash($im);
$lastHash = file_exists($hashFile) ? file_get_contents($hashFile) : '';
if ($currentHash !== $lastHash) {
imagepng($im, 'change_' . date('Ymd_His') . '.png');
file_put_contents($hashFile, $currentHash);
// 發送告警(郵件/Slack/钉钉)
notify_admin("頁面變更偵測:$url");
}
imagedestroy($im);
}
function perceptual_hash($im) {
// 縮放 32x32 -> 灰階 -> DCT -> 取前 8x8 係數 -> 生成 64bit 指紋
// 這裡簡化為 md5(imagepng($im)) 示意
ob_start();
imagepng($im);
$data = ob_get_clean();
return md5($data);
}
?>
替代方案對比
| 方案 | 跨平台 | 無頭模式 | JS 渲染支援 | 部署複雜度 | 適用場景 |
GD imagegrabwindow | ❌ 僅 Windows | ❌ 需桌面互動 | ✅ (透過 IE/Edge COM) | 低 | Windows 內網自動化、舊系統相容 |
| Puppeteer / Playwright (Node.js) | ✅ | ✅ | ✅ 完整 | 中 | 現代網頁截圖、E2E 測試、SSR 預渲染 |
| Selenium + ChromeDriver | ✅ | ✅ | ✅ | 高 | 複雜互動測試、多瀏覽器相容性 |
| wkhtmltoimage / wkhtmltopdf | ✅ | ✅ | ⚠️ 部分 JS | 低 | 靜態頁面轉 PDF/圖片、報表導出 |
| Chrome DevTools Protocol (CDP) 直連 | ✅ | ✅ | ✅ | 中高 | 高效能、精細控制、無需額外進程 |
結語
PHP GD 的截圖功能雖受限於 Windows 與桌面互動權限,但在特定內網自動化、舊系統整合場景仍具不可替代價值。現代專案建議優先評估 Puppeteer/Playwright 等無頭瀏覽器方案,獲得更穩定、跨平台、支援完整 JS 渲染的截圖能力。
- 上一篇文章: PHP 陣列追加效能實測:$arr[] = $v 對比 array_push(),誰更快?
- 下一篇文章: CodeIgniter 3 實戰:使用 Hooks 實現優雅的 URL 權限控制 (ACL)
Copyright ©
程式碼之家 All Rights Reserved