Ben*_*Ben 10 java javafx webview javafx-8 javafx-webengine
我想在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);
}
}
Run Code Online (Sandbox Code Playgroud)
WebView类包含以下函数:
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;
}
Run Code Online (Sandbox Code Playgroud)
只要函数返回 false,渲染就会被阻止。所以让它渲染起来可能相当棘手。通常,对于快照,您根本不必将节点放入场景中。
| 归档时间: |
|
| 查看次数: |
1483 次 |
| 最近记录: |