问题描述
我想从JavaFX(8)中的WebView创建SnapShot/屏幕截图/图像.
此WebView不需要可见(在我的情况下).
我的问题:
当WebView 不可见(或未添加到任何可见容器)时,是否可以(以任何方式)从WebView创建屏幕截图/图像?
I want to create a SnapShot/Screenshot/Image from a WebView in JavaFX(8).
This WebView does not need to be visible (in my case).
My question:
Is it possible (in any way), to create a Screenshot/Image from a WebView,
when the WebView is not visible (or not added to any visible container)?
当WebView(或其父级ScrollPane)为 visible = false 时,请参阅我的示例代码,
截图将无效(分别为空/空白).
See my example code, when WebView (or it's parent ScrollPane) is visible=false,
the Screenshot won't work (respectively is 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);
}
}
推荐答案
WebView类包含以下功能:
The class WebView contains the following function:
private boolean isTreeReallyVisible() {
if (getScene() == null) {
return false;
}
final Window window = getScene().getWindow();
if (window == null) {
return false;
}
boolean iconified = (window instanceof Stage) ? ((Stage)window).isIconified() : false;
return impl_isTreeVisible()
&& window.isShowing()
&& window.getWidth() > 0
&& window.getHeight() > 0
&& !iconified;
}
只要函数返回false,就会阻止渲染.因此,使其呈现可能非常棘手.通常,对于快照,您根本不需要将Node放在场景中.
As long as the function returns false, the rendering is blocked. So it might be quite tricky to get it to render. Normally, for snapshot you don't have to put the Node in the scene at all.
这篇关于JavaFX-如何创建(隐形)WebView的快照/屏幕快照的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!