JavaFX 2.0+ WebView / WebEngine将网页呈现给图像

我正在寻找一种加载页面并将渲染保存为图像的方法,就像使用CutyCapt一样(QT + webkit EXE就是这样)。

目前并且没有JavaFX,我通过从java调用外部进程并渲染到文件而不是将该文件加载到ImageBuffer中来实现…既不优化也不实用,甚至更少跨平台…

使用JavaFX2 +我尝试使用WebView和WebEngine:

public class WebComponentTrial extends Application { private Scene scene; @Override public void start(final Stage primaryStage) throws Exception { primaryStage.setTitle("Web View"); final Browser browser = new Browser(); scene = new Scene(browser, 1180, 800, Color.web("#666970")); primaryStage.setScene(scene); scene.getStylesheets().add("webviewsample/BrowserToolbar.css"); primaryStage.show(); } public static void main(final String[] args) { launch(args); } } class Browser extends Region { static { // use system proxy settings when standalone application // System.setProperty("java.net.useSystemProxies", "true"); } final WebView browser = new WebView(); final WebEngine webEngine = browser.getEngine(); public Browser() { getStyleClass().add("browser"); webEngine.load("http://www.google.com/"); getChildren().add(browser); } @Override protected void layoutChildren() { final double w = getWidth(); final double h = getHeight(); layoutInArea(browser, 0, 0, w, h, 0, HPos.CENTER, VPos.CENTER); } @Override protected double computePrefWidth(final double height) { return 800; } @Override protected double computePrefHeight(final double width) { return 600; } } 

有一个不赞成使用的方法: renderToImage中的renderToImage (参见下面的链接),它可以做一些接近我可能能够工作的东西,但它已被弃用……在JavaFX中被弃用似乎意味着有没有javadoc广告替换方法,因为我无法访问代码,我看不出它是如何完成的……

以下是我发现一些信息的几个网站,但没有任何内容可以将网页呈现给图像:

 http://tornorbye.blogspot.com/2010/02/how-to-render-javafx-node-into-image.html 

canvasImagesaveImage(canvasImage, fc.getSelectedFile())来自这个:

 http://javafx.com/samples/EffectsPlayground/src/Main.fx.html 

其他:

 http://download.oracle.com/javafx/2.0/webview/jfxpub-webview.htm http://download.oracle.com/javafx/2.0/get_started/jfxpub-get_started.htm http://fxexperience.com/2011/05/maps-in-javafx-2-0/ 

我通过在Swing JFrame和JFXPanel上启动JavaFX WebView来完成此操作。 然后,一旦WebEngine状态为SUCCEEDED,我就在JFXPanel上使用paint()方法。

您可以按照本教程制作WebView: 将JavaFX集成到Swing应用程序中

下面的代码演示了如何从JFXPanel捕获渲染的屏幕。

 public static void main(String args[]) { jFrame = new JFrame("Demo Browser"); jfxPanel = new JFXPanel(); jFrame.add(jfxPanel); jFrame.setVisible(true); jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { Platform.runLater(new Runnable() { @Override public void run() { browser = new FXBrowser(); jfxPanel.setScene(browser.getScene()); jFrame.setSize((int) browser.getWebView().getWidth(), (int) browser.getWebView().getHeight()); browser.getWebEngine().getLoadWorker().stateProperty().addListener( new ChangeListener() { @Override public void changed(ObservableValue observable, Object oldValue, Object newValue) { State oldState = (State) oldValue; State newState = (State) newValue; if (State.SUCCEEDED == newValue) { captureView(); } } }); } }); } }); } private static void captureView() { BufferedImage bi = new BufferedImage(jfxPanel.getWidth(), jfxPanel.getHeight(), BufferedImage.TYPE_INT_ARGB); Graphics graphics = bi.createGraphics(); jfxPanel.paint(graphics); try { ImageIO.write(bi, "PNG", new File("demo.png")); } catch (IOException e) { e.printStackTrace(); } graphics.dispose(); bi.flush(); } 

对于JavaFX 2.2用户,基于JavaFX Node快照有一个更加干净和优雅的解决方案。 您可以在以下位置查看JavaFX节点文档:

http://sofzh.miximages.com/java/ppre code File destFile = new File(test.png”); WritableImage snapshot = webView.snapshot(new SnapshotParameters(), null); RenderedImage renderedImage = SwingFXUtils.fromFXImage(snapshot, null); try { ImageIO.write(renderedImage, “png”, destFile); } catch (IOException ex) { Logger.getLogger(GoogleMap.class.getName()).log(Level.SEVERE, null, ex); }

我对此解决方案没有任何问题,并且根据节点大小在WebG中完美呈现webview。 可以使用此方法呈现任何JavaFx节点并将其保存到文件中。

希望这有帮助!

JavaFX工程师发布的解决方法: 快照不适用于(不可见)WebView节点 。

拍摄包含WebView节点的场景的快照时,请在发出快照命令之前至少等待2帧。 这可以通过使用AnimationTimer中的计数器跳过2个脉冲并在第3个脉冲上拍摄快照来完成。

获得快照后,您可以将图像转换为awt BufferedImage,并使用ImageIO将图像编码为png或jpg等格式。