Chcę utworzyć SnapShot/Screenshot/Obraz z WebView w JavaFX (8).
Ten WebView nie musi być widoczny (w moim przypadku).
Moje pytanie:
Czy to możliwe (w jakikolwiek sposób), aby utworzyć zrzut ekranu/Obraz z WebView,
gdy WebView jest niewidoczna (lub nie dodaje się do jakichkolwiek widocznych pojemniku)?JavaFX - Jak utworzyć SnapShot/Zrzut ekranu (niewidoczny) WebView
Zobacz mój przykładowy kod, gdy WebView (lub jego rodzic ScrollPane) jest widoczne = false,
screenie nie zadziała (odpowiednio jest pusty/pusty).
Przykład Kod:
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);
}
}
Czy chcesz zrobić migawkę bez pokazywania aplikacji lub sceny? – Sanshayan
Moja aplikacja pokazuje (i ma w wyniku tego scenę). Ale ten WebView nie musi być jego częścią. – Ben
To jest jakaś żądana funkcja, która jest nierozwiązana, jak na ten [problem] (https://javafx-jira.kenai.com/browse/RT-23265) na Jira. Przetestowałem 8u60b13 (nowa implementacja webkita), bez powodzenia. Myślę, że masz dobre obejście. –