不建议使用未记录的com.sun API。
相反,您可以snapshot WebView 节点,并使用来自snapshot Image 的PixelReader 来获取像素缓冲区。
我不确定这是否正是您想要做的。可能还有其他方法可以实现您想要的(例如覆盖窗口而不是使用缓冲区)。
这是一个将动画 WebView 节点(播放视频)连续拍摄到 ImageView 中的示例。
图片顶部是原始网页视图。图像的底部是原始图像的快照,其中覆盖了帧速率(当原始源 WebView 调整为全屏时,在 Retina MacBook 上运行时约为 60fps)。可以修改示例代码中的 W 和 H 值,以检查不同图像捕获尺寸的性能。
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.concurrent.Worker;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.image.*;
import javafx.scene.layout.*;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
public class VideoPlayerWithFrameByFrameSnapshot extends Application {
private static final int W = 800;
private static final int H = 400;
private final long[] frameTimes = new long[100];
private int frameTimeIndex = 0 ;
private boolean arrayFilled = false ;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
// create a WebView
WebView webview = new WebView();
webview.setMinSize(W, H);
webview.setPrefSize(W, H);
webview.setMaxSize(W, H);
// create an image viewer for a WebView snapshot
WritableImage image = new WritableImage(W, H);
ImageView imageview = new ImageView(image);
Label framerateLabel = new Label();
// continuously snapshot the webview and measure current framerate.
AnimationTimer timer = new AnimationTimer() {
@Override
public void handle(long now) {
webview.snapshot(null, image);
long oldFrameTime = frameTimes[frameTimeIndex] ;
frameTimes[frameTimeIndex] = now ;
frameTimeIndex = (frameTimeIndex + 1) % frameTimes.length ;
if (frameTimeIndex == 0) {
arrayFilled = true ;
}
if (arrayFilled) {
long elapsedNanos = now - oldFrameTime ;
long elapsedNanosPerFrame = elapsedNanos / frameTimes.length ;
double frameRate = 1_000_000_000.0 / elapsedNanosPerFrame ;
framerateLabel.setText(
String.format(
"Current frame rate: %.3f",
frameRate
)
);
}
}
};
// start the snapshot process once the web view load succeeds.
webview.getEngine().getLoadWorker().stateProperty().addListener(
(observable, oldValue, newValue) -> {
System.out.println(newValue);
if (Worker.State.SUCCEEDED == newValue) {
timer.start();
}
}
);
// load up the big buck bunny video.
webview.getEngine().load(
"http://camendesign.com/code/video_for_everybody/test.html"
);
// layout the scene.
VBox layout = new VBox(
webview,
new StackPane(
imageview,
framerateLabel
)
);
StackPane.setAlignment(framerateLabel, Pos.TOP_LEFT);
stage.setScene(new Scene(layout));
stage.show();
}
}
帧率测量代码来自 James_D 的回答:
顺便说一句:如果你想用纯 HTML UI 制作游戏,那么我不明白你为什么会涉及 libgdx 并希望访问低级绘图原语来捕获嵌入式浏览器的图形输出(而不是不仅仅是在用户的默认浏览器中或直接在游戏附带的嵌入式浏览器中显示 HTML UI),但我想你有理由采用这种方法。将来,我将尽量避免尝试回答动机和目标不明确的问题。这不是一个坏问题,只是一个我认为我无法提供太多帮助的问题。