我正在尝试为我的绘图应用创建一个演示文稿视图,其中只有绘图板(窗格)可见。因此,用户可以在PC上显示实际绘图窗格和工具的同时在投影仪上显示演示视图。
我目前的做法是从每个框架的窗格创建一个快照,并在第二个阶段的ImageView中显示它。
public void startStream(){
new AnimationTimer() {
@Override
public void handle(long now) {
WritableImage image = drawingPane.snapshot(new SnapshotParameters(), null);
stream.setImage(image);
}
}.start();
final Screen screen = Screen.getPrimary();
final Stage stage = new Stage();
StackPane root = new StackPane();
root.getChildren().add(stream);
Scene scene = new Scene(root, drawingPane.getWidth(), drawingPane.getHeight());
stage.setScene(scene);
stage.setTitle("streaming stage");
Rectangle2D bounds = screen.getBounds();
System.out.println(bounds);
stage.setX(bounds.getMinX() + (bounds.getWidth() - 300) / 2);
stage.setY(bounds.getMinY() + (bounds.getHeight() - 200) / 2);
stage.show();
}
这里的问题是它占用了大量的内存,比如800MB,CPU使用率也增加了30%。我可以理解,在每一帧上创建一个图像效率不高,这就是为什么我想问,如果有办法让这个工作更有效率。
此外,如果有更好的方法/解决方案,我会感激它。
答案 0 :(得分:2)
要降低CPU使用率,请不要在AnimationTimer中创建快照 - 这实际上会以帧速率(60 FPS)频率生成快照,即使drawingPane
中没有任何更改也是如此。而是在drawingPane
布局后制作快照。向drawingPane
的{{1}}添加一个监听器应该可以解决问题:
needsLayoutProperty
当您不编辑drawingPane.needsLayoutProperty().addListener((obs, wasDirty, isDirty) -> {
if(!isDirty) {
WritableImage image = drawingPane.snapshot(new SnapshotParameters(), null);
stream.setImage(image);
}
});
时,这应该会降低CPU使用率。
它还可能降低内存使用量,因为垃圾收集器可能会更快地启动并收集旧快照。如果没有,请考虑重新使用drawingPane
实例,如果它已经具有正确的大小:
WritableImage
注意,此答案假定WritableImage image = null;
drawingPane.needsLayoutProperty().addListener((obs, wasDirty, isDirty) -> {
if(!isDirty) {
if(this.image != null &&
(this.image.getWidth() != drawingPane.getWidth() ||
this.image.getHeight() != drawingPane.getHeight())) {
this.image = null;
}
this.image = drawingPane.snapshot(new SnapshotParameters(), this.image);
stream.setImage(this.image);
}
});
的孩子是托管的子女(这是默认设置),因此他们的布局被标记为脏导致drawingPane
的布局被标记为脏,以便您可以实际观察drawingPane
属性的任何更改。