JPanel.getGraphics эквивалент в JavaFx для использования с OpenCV

Название кажется немного запутанным, но я все объясню.

Я разрабатываю проект, в котором я показываю изображение, снятое веб-камерой в JPanel, Java Swing. Теперь я должен интегрировать это с JavaFx. У меня есть контроллер, где у меня есть метод startRecording, который инициализирует cameraThread и сообщает классу Camera startRecording, внутри класса Camera есть метод DrawFrame(BufferedImage, панель JPanel), где я вызываю функцию drawImage из OpenCV для рисования в Группа:

контроллер:

public void startRecording(){
    cameraInstance.setCameraRGBPanel(windowsInstance.getCameraRGBPanel());
    cameraInstance.setCameraHSVPanel(windowsInstance.getCameraHSVPanel());
    cameraInstance.setCameraThresholdPanel(windowsInstance.getCameraThresholdPanel());
    cameraInstance.setRecord(true);
    cameraThread = new Thread(cameraInstance);
    cameraThread.start();
}

Класс камеры:

private void drawFrame(BufferedImage buff, JPanel pane){
    pane.getGraphics().drawImage(buff, 0, 0, null);
}

Начнем с того, что в JavaFX нет JPanel, а в панели (опция) нет getGraphics, я попытался использовать SwingNode, добавить JPanel, а затем делать все как обычно, но изображение просто не будет отображаться.

Следующий код был тестом, поэтому он кажется "плохим".

public void start(Stage stage) throws Exception {

    stage.setTitle("Tela Teste");

    pCamera = new Pane();
    SwingNode swing = new SwingNode();
    pCamera.getChildren().add(swing);
    createAndSetSeingContent(swing);

    Group root = new Group();
    root.getChildren().add(pCamera);
    stage.setScene(new Scene(root , 500, 500));
    stage.setResizable(true);
    stage.show();
}

private void createAndSetSeingContent(SwingNode swing) {                
    ControllerCamera control = new ControllerCamera();
    System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

    JPanel panel = new JPanel();
    JLabel label = new JLabel("Abc");
    //panel.add(label);
    swing.setContent(panel);

    Button teste = new Button("A");
    pCamera.getChildren().add(teste);
    teste.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            control.startRecording(panel);
            System.out.println("abc");
        }
    });
}

Я изменил метод startRecording на что-то вроде:

public void startRecording(JPanel panel){
    cameraInstance.setCameraRGBPanel(panel);
    cameraInstance.setRecord(true);
    cameraThread = new Thread(cameraInstance);
    cameraThread.start();
}

Все еще ничего не появляется на панели, но если я добавлю ярлык или кнопку, то он появится и будет работать так, как задумано. "Abc" всегда отображается в консоли.

Я думаю, что это весь код, связанный с проблемой. Что-то еще, что я хочу сказать, это то, что вчера был первый день, когда я имел дело с FX, скажем, проект разделен, другой парень также работает над проблемой, но мы до сих пор нигде не нашли, поэтому я решил спросить тебя здесь.

Правка 1: до этой ситуации все работало идеально (все работает с Swing, но не с FX).

1 ответ

Решение

Самый простой способ отобразить изображение в JavaFX - это ImageView, Вы можете создать один ImageView и обновить его изображение, позвонив setImage(...) проходя в javafx.scene.image.Image, Я не знаю API камеры, с которым вы работаете: возможно, вы сможете сгенерировать изображение JavaFX напрямую, и в этом случае ваш метод рисования рамки выглядит так просто:

private void drawFrame(Image image, ImageView imageView) {
    imageView.setImage(image);
}

Если вы можете только генерировать BufferedImage с, вы можете сделать

private void drawFrame(BufferedImage buff, ImageView imageView) {
    imageView.setImage(SwingFXUtils.toFXImage(buff, null));
}

В любом случае вы можете просто создать ImageView положить его в Pane подкласс какой-то, положить Pane в сцене и отобразить ее в Stage:

public void start(Stage stage) throws Exception {

    stage.setTitle("Tela Teste");

    pCamera = new Pane();
    ImageView imageView = new ImageView();
    pCamera.getChildren().add(imageView);

    Group root = new Group();
    root.getChildren().add(pCamera);
    stage.setScene(new Scene(root , 500, 500));
    stage.setResizable(true);
    stage.show();
}

Тогда просто передайте imageView на ваш drawFrame метод по мере необходимости.

Другие вопросы по тегам