Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
javafx2.0+;WebView/WebEngine将网页渲染为图像_Java_Image_Save_Render_Javafx - Fatal编程技术网

javafx2.0+;WebView/WebEngine将网页渲染为图像

javafx2.0+;WebView/WebEngine将网页渲染为图像,java,image,save,render,javafx,Java,Image,Save,Render,Javafx,我正在寻找一种加载页面并将渲染保存为图像的方法,就像使用CutyCapt(QT+webkit EXE)一样 目前,在没有JavaFX的情况下,我通过从java调用一个外部进程并将其渲染到文件,而不是将该文件加载到ImageBuffer中来实现这一点。。。既不是非常优化也不实用,更不是跨平台的 使用JavaFX2+我尝试使用WebView和WebEngine: 公共类WebComponentTrial扩展了应用程序{ 私密场景; @凌驾 public void start(final Stage

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

目前,在没有JavaFX的情况下,我通过从java调用一个外部进程并将其渲染到文件,而不是将该文件加载到ImageBuffer中来实现这一点。。。既不是非常优化也不实用,更不是跨平台的

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

公共类WebComponentTrial扩展了应用程序{
私密场景;
@凌驾
public void start(final Stage primaryStage)引发异常{
primaryStage.setTitle(“Web视图”);
最终浏览器=新浏览器();
场景=新场景(浏览器,1180800,Color.web(“#666970”);
初级阶段。场景(场景);
scene.getStylesheets().add(“webviewsample/BrowserToolbar.css”);
primaryStage.show();
}
公共静态void main(最终字符串[]args){
发射(args);
}
}
类浏览器扩展区域{
静态{//独立应用程序运行时使用系统代理设置
//setProperty(“java.net.useSystemProxies”,“true”);
}
最终WebView浏览器=新WebView();
final-WebEngine-WebEngine=browser.getEngine();
公共浏览器(){
getStyleClass().add(“浏览器”);
webEngine.load(“http://www.google.com/");
getChildren().add(浏览器);
}
@凌驾
受保护的void layoutChildren(){
最终双精度w=getWidth();
最终双h=getHeight();
布局区域(浏览器、0、0、w、h、0、HPos.CENTER、VPos.CENTER);
}
@凌驾
受保护的双计算参考宽度(最终双高度){
返回800;
}
@凌驾
受保护的双计算参考高度(最终双宽度){
返回600;
}
}
有一种不推荐使用的方法:
renderToImage
中的
Scene
(请参见下面的链接),它可以做一些接近的事情,我可能可以使用它,但它不推荐使用。。。 在JavaFX中被弃用似乎意味着没有javadoc宣传替换方法,因为我没有访问代码的权限,我看不到它是如何完成的

这里有几个网站,我在其中找到了一些信息,但没有找到将网页渲染为图像的信息:

http://tornorbye.blogspot.com/2010/02/how-to-render-javafx-node-into-image.html
canvasImage
saveImage(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上启动JavaFXWebView来实现这一点。一旦WebEngine状态成功,我就在JFXPanel上使用paint()方法

您可以按照本教程制作网络视图:

下面的代码演示如何从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个脉冲并在第3个脉冲上拍摄快照来实现


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

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

下面是从WebView节点(作为WebView)获取捕获的示例

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


希望这有帮助

但是无头截屏呢?所以我可以在服务器端启动它,像PhantomJS抱歉,但我不理解你,我只是想找一个工作示例,可以在不显示任何表单/框架的情况下拍摄快照-“headless”。与启动应用程序一样,它会对我传递的任何html进行快照,而不会在屏幕上显示任何窗口。就像PhantomJS一样。我会使用
print
printAll
而不是
paint
,但基本思想非常酷!什么是FXBrowser?你曾经让它工作过吗?我无法让WebView向图像写入任何内容,除非我将其实际附加到场景并在舞台上显示。
   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);
   }