利用 Swing 的 JEditorPane 渲染 HTML,再透過 Graphics2D 繪製到 BufferedImage,最後用 ImageIO 輸出 JPG/PNG。此方案純 Java 實現,無需外部瀏覽器引擎,適合服務端自動化截圖場景。
setVisible(true) 必須開啟,否則圖片資源無法下載渲染;無頭環境需配置 Xvfb 或使用 Headless 模式Thread.sleep() 給網頁資源(圖片、CSS、JS)下載時間,實際專案建議改用 PropertyChangeListener 監聽 page 屬性setSize(10000,10000) 再 pack(),確保完整內容渲染不被截斷AffineTransform.getScaleInstance() 配合 RenderingHints.VALUE_RENDER_QUALITY 實現高質量縮圖public class WebSnapshot extends JFrame {
public WebSnapshot(String url, File output) throws Exception {
JEditorPane editor = new JEditorPane();
editor.setEditable(false);
editor.setPage(url); // 載入網頁
JScrollPane scroll = new JScrollPane(editor);
getContentPane().add(scroll);
setLocation(0, 0);
setVisible(true); // 關鍵:觸發渲染
Thread.sleep(5000); // 等待資源加載
setSize(10000, 10000);
pack(); // 適應內容大小
BufferedImage fullImg = new BufferedImage(
editor.getWidth(), editor.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = fullImg.createGraphics();
editor.paint(g2d); // 繪製到圖片
g2d.dispose();
BufferedImage thumb = resize(fullImg, 600, 400); // 等比縮放
ImageIO.write(thumb, "jpg", output); // 輸出文件
dispose();
}
// 等比縮放輔助方法
public static BufferedImage resize(BufferedImage src, int w, int h) {
double sx = (double) w / src.getWidth();
double sy = (double) h / src.getHeight();
if (sx > sy) { sx = sy; w = (int)(sx * src.getWidth()); }
BufferedImage target = new BufferedImage(w, h, src.getType());
Graphics2D g = target.createGraphics();
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.drawRenderedImage(src, AffineTransform.getScaleInstance(sx, sy));
g.dispose();
return target;
}
}
-Djava.awt.headless=true(但會導致圖片無法渲染)BufferedImage 佔用堆外內存,及時 dispose() 並考慮分塊處理超長頁面JEditorPane 方案適合簡單靜態頁面、報表輸出、內部系統截圖等場景。對於現代 Web 應用(SPA、動態渲染、Canvas/WebGL),請採用無頭瀏覽器方案。理解其原理與限制,才能在技術選型中做出正確決策。