使用Robot的JavaFX捕获屏幕

时间:2016-09-07 14:52:56

标签: java canvas javafx

我在JavaFX中使用透明的Stage,其中包含Canvas

用户可以通过拖动鼠标在画布中绘制rectangle

  

当他点击输入时,我将使用以下方式保存图像:

try {
     ImageIO.write(bufferedImage,extension,outputFile);
} catch (IOException e) {
    e.printStackTrace();                        
}
  

从我正在使用的屏幕捕获image

gc.clearRect(0, 0, getWidth(), getHeight()); // [gc] is the graphicsContext2D of the Canvas

        // Start the Thread
        new Thread(() -> {
            try {

                // Sleep some time
                Thread.sleep(100);

                // Capture the Image
                BufferedImage image;
                int[] rect = calculateRect();
                try {
                    image = new Robot().createScreenCapture(new Rectangle(rect[0], rect[1], rect[2], rect[3]));
                } catch (AWTException e) {
                    e.printStackTrace();
                    return;
                }

            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }).start();
  

问题

我不知道JavaFX Thread什么时候会清除Canvas所以我正在使用Thread,正如您在上面看到的那样等待 100毫秒然后捕获屏幕。但它一直没有工作,我的意思是有时Canvas尚未清除,我得到这个图像(原因Canvas尚未清除):

enter image description here

而不是:

enter image description here

  

问题:

我如何知道JavaFX何时清除了Canvas,以便我可以在此之后捕获屏幕?

不建议将SwingJavaFX混合使用,尽管这是我知道使用Java捕获屏幕的唯一方法...

1 个答案:

答案 0 :(得分:1)

我真的希望有更好的方法来实现你想要的东西,但画布将在下次渲染“脉冲”时被清除。因此,一种方法是启动AnimationTimer并等待呈现第二帧:

gc.clearRect(0, 0, getWidth(), getHeight());
AnimationTimer waitForFrameRender = new AnimationTimer() {
    private int frameCount = 0 ;
    @Override
    public void handle(long timestamp) {
        frameCount++ ;
        if (frameCount >= 2) {
            stop();
            // now do screen capture...
        }
    }
};
waitForFrameRender.start();

显然,如果你在后台线程中进行屏幕捕获,你还需要确保在捕获发生之前不要回到画布上......