這裏是在web視圖拍攝動畫的一個例子。
從網絡視圖捕獲的圖像被放置在Paginator中進行查看,以便查看它們。如果您願意,您可以使用SwingFXUtils
和ImageIO
將它們寫出到文件中。如果你想將得到的圖像存入緩衝區,你可以使用它們的PixelReader
。
這完全不是那麼回事我想它的方式。我想快照WebView而不將其放置在可見的舞臺上。但是,對於不在舞臺中的節點拍攝快照對於JavaFX中的每個其他節點類型都能正常工作(據我所知),但出於某種奇怪的原因,它不適用於WebView。因此,示例實際上在顯示窗口後創建了一個新的Stage,該窗口顯示動畫捕獲結果的圖像序列。我知道,你不想要的東西,但它是它是什麼......
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.beans.property.*;
import javafx.collections.*;
import javafx.concurrent.Worker;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.SnapshotParameters;
import javafx.scene.control.*;
import javafx.scene.image.*;
import javafx.scene.layout.*;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
public class WebViewAnimationCaptor extends Application {
private static final String CAPTURE_URL =
"https://upload.wikimedia.org/wikipedia/commons/d/dd/Muybridge_race_horse_animated.gif";
private static final int N_CAPS_PER_SECOND = 10;
private static final int MAX_CAPTURES = N_CAPS_PER_SECOND * 5;
private static final int W = 186, H = 124;
class CaptureResult {
ObservableList<Image> images = FXCollections.observableArrayList();
DoubleProperty progress = new SimpleDoubleProperty();
}
@Override public void start(Stage stage) {
CaptureResult captures = captureAnimation(CAPTURE_URL);
Pane captureViewer = createCaptureViewer(captures);
stage.setScene(new Scene(captureViewer, W + 40, H + 80));
stage.show();
}
private StackPane createCaptureViewer(CaptureResult captures) {
ProgressIndicator progressIndicator = new ProgressIndicator();
progressIndicator.progressProperty().bind(captures.progress);
progressIndicator.setPrefSize(W, H);
StackPane stackPane = new StackPane(progressIndicator);
stackPane.setPadding(new Insets(10));
if (captures.progress.get() >= 1.0) {
stackPane.getChildren().setAll(
createImagePages(captures.images)
);
} else {
captures.progress.addListener((observable, oldValue, newValue) -> {
if (newValue.doubleValue() >= 1.0) {
stackPane.getChildren().setAll(
createImagePages(captures.images)
);
}
});
}
return stackPane;
}
private Pagination createImagePages(ObservableList<Image> captures) {
Pagination pagination = new Pagination();
pagination.setPageFactory(param -> {
ImageView currentImage = new ImageView();
currentImage.setImage(
param < captures.size()
? captures.get(param)
: null
);
StackPane pageContent = new StackPane(currentImage);
pageContent.setPrefSize(W, H);
return pageContent;
});
pagination.setCurrentPageIndex(0);
pagination.setPageCount(captures.size());
pagination.setMaxPageIndicatorCount(captures.size());
return pagination;
}
private CaptureResult captureAnimation(final String url) {
CaptureResult captureResult = new CaptureResult();
WebView webView = new WebView();
webView.getEngine().load(url);
webView.setPrefSize(W, H);
Stage captureStage = new Stage();
captureStage.setScene(new Scene(webView, W, H));
captureStage.show();
SnapshotParameters snapshotParameters = new SnapshotParameters();
captureResult.progress.set(0);
AnimationTimer timer = new AnimationTimer() {
long last = 0;
@Override
public void handle(long now) {
if (now > last + 1_000_000_000.0/N_CAPS_PER_SECOND) {
last = now;
captureResult.images.add(webView.snapshot(snapshotParameters, null));
captureResult.progress.setValue(
captureResult.images.size() * 1.0/MAX_CAPTURES
);
}
if (captureResult.images.size() > MAX_CAPTURES) {
captureStage.hide();
this.stop();
}
}
};
webView.getEngine().getLoadWorker().stateProperty().addListener((observable, oldValue, newValue) -> {
if (Worker.State.SUCCEEDED.equals(newValue)) {
timer.start();
}
});
return captureResult;
}
public static void main(String[] args) { launch(args); }
}
要微調動畫序列捕獲,你可以審查這個info on AnimationTimers in JavaFX。
如果你需要讓事物「無頭」,以便不需要可見的舞臺,你可以試試gist by danialfarid which performs "Java Image Capture, HTML Snapshot, HTML to image"(儘管我沒有寫出鏈接的要點,但沒有嘗試過)。
無頭是關鍵,在我的情況。有問題的(linux)機器在服務器場中完全無法運行。至於主旨,我在那裏看到一個節目(),但我會仔細觀察一下,以確保我沒有忽略某些東西。
該要點基於Monocle glass rendering toolkit for JavaFX systems。該工具包支持在任何系統上進行基於軟件的無頭渲染。
從Monocle Documentation:
無頭端口什麼都不做。當你想運行沒有圖形,輸入或平臺依賴的JavaFX時。渲染仍然發生,它只是不顯示在屏幕上。
無頭端口使用InputDeviceRegistry的LinuxInputDeviceRegistry執行。然而,無頭端口根本不訪問任何實際的Linux設備或任何本地API;它在設備模擬模式下使用Linux輸入註冊表。這樣即使在非Linux平臺上也可以模擬Linux設備輸入。 tests/system/src/test/java/com/sun/glass/ui/monocle/input中的測試廣泛使用了此功能。
如果JavaFX的單片眼鏡基礎的做法最終不會爲你工作了,你可以考慮另一種(不相關的JavaFX)無頭的HTML渲染套件,如PhantomJS。
無頭是我的關鍵。有問題的(linux)機器在服務器場中完全無法運行。至於主旨,我在那裏看到一個節目(),但我會仔細觀察一下,以確保我沒有忽略某些東西。謝謝! – lagnat