JavaFX – 如何创建SnapShot /(invisble)WebView的屏幕截图

我想在 JavaFX(8)中的WebView中创建一个SnapShot / Screenshot / Image.这个WebView不需要可见(在我的情况下).
我的问题:
当WebView不可见(或不添加到任何可见容器)时,是否可以(从任何方式)创建一个WebView的屏幕截图/图像?

看到我的示例代码,当WebView(或它的父ScrollPane)可见= false时,
屏幕截图将不起作用(分别是emtpy / blank).

示例代码

package test;

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.value.changelistener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.SnapshotResult;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.ImageView;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import javafx.util.Duration;

public class JavaFXApplication extends Application
{
   @Override
   public void start(Stage primaryStage)
   {
      ImageView webviewPreviewImage = new ImageView();
      Label waitLabel = new Label("Please wait...");
      WebView webView = new WebView();
      webView.setMaxHeight(480d);
      webView.setMinHeight(480d);
      webView.setMaxWidth(640d);
      webView.setMinWidth(640d);
      webView.setZoom(0.4);

      ScrollPane scrollpane = new ScrollPane(webView);
      scrollpane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
      scrollpane.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
      scrollpane.setMaxWidth(0); //WORKAROUND: hide the WebView/ScrollPane
      scrollpane.setMaxHeight(0); //WORKAROUND: hide the WebView/ScrollPane
      scrollpane.setMinWidth(0); //WORKAROUND: hide the WebView/ScrollPane
      scrollpane.setMinHeight(0); //WORKAROUND: hide the WebView/ScrollPane

      //scrollpane.setVisible(false); //when WebView is invisible,SnapShot doesn't work!

       webView.getEngine().getLoadWorker().stateproperty().addListener(new changelistener<Worker.State>() 
       {
          @Override
          public void changed(ObservableValue ov,Worker.State oldState,Worker.State newState) 
          {
              if (newState == Worker.State.SUCCEEDED) 
              {
                 //When SUCCEEDED is called,the WebPage may not has fully finished rendering!
                 //so,wait for few seceonds before making the screenshot...
                 Timeline timeline = new Timeline(new KeyFrame(
                         Duration.millis(1500),ae -> takeSnapshot()));
                 timeline.play();
              }
           }

           private KeyFrame takeSnapshot()
           {
              webView.snapshot((SnapshotResult param) ->
              {
                 webviewPreviewImage.setimage(param.getimage());
                 webviewPreviewImage.setFitHeight(240d);
                 webviewPreviewImage.setFitWidth(320d);
                 webviewPreviewImage.setPreserveRatio(true);
                 waitLabel.setVisible(false);
                 return null;
              },null,null);
              return null;
          }
      });
      webView.getEngine().load("http://www.bing.com");

      VBox root = new VBox();
      root.setAlignment(Pos.CENTER);
      root.setSpacing(10d);
      root.getChildren().add(waitLabel);
      root.getChildren().add(scrollpane);
      root.getChildren().add(webviewPreviewImage);

      Scene scene = new Scene(root,800,600);
      primaryStage.setScene(scene);
      primaryStage.show();
  }

  public static void main(String[] args)
  {
     launch(args);
  }
}

解决方法

使用机器人类来模拟按键(Fn和PrintScreen),加载并裁剪.

相关文章

应用场景 C端用户提交工单、工单创建完成之后、会发布一条工...
线程类,设置有一个公共资源 package cn.org.chris.concurre...
Java中的数字(带有0前缀和字符串)
在Java 9中使用JLink的目的是什么?
Java Stream API Filter(过滤器)
在Java中找到正数和负数数组元素的数量