JPanel.getGraphics 在 JavaFx 中等效于与 OpenCV 一起使用
JPanel.getGraphics equivalent in JavaFx to use with OpenCV
标题好像有点乱,不过我会一一解释的。
我正在开发一个项目,我在 JPanel Java Swing 中显示网络摄像头捕获的图像。现在我必须将其与 JavaFx 集成。
我有一个控制器,其中有方法 startRecording,它会初始化 cameraThread 并告诉 class Camera 开始记录,在 Camera class 里面有一个方法 DrawFrame(BufferedImage, JPanel panel) 我调用来自 OpenCV 的函数 drawImage 在面板中绘制:
控制器:
public void startRecording(){
cameraInstance.setCameraRGBPanel(windowsInstance.getCameraRGBPanel());
cameraInstance.setCameraHSVPanel(windowsInstance.getCameraHSVPanel());
cameraInstance.setCameraThresholdPanel(windowsInstance.getCameraThresholdPanel());
cameraInstance.setRecord(true);
cameraThread = new Thread(cameraInstance);
cameraThread.start();
}
Class 相机:
private void drawFrame(BufferedImage buff, JPanel pane){
pane.getGraphics().drawImage(buff, 0, 0, null);
}
首先,JavaFX 没有 JPanel,Pane(一个选项)也没有 getGraphics,我尝试使用 SwingNode,添加 JPanel,然后照常执行所有操作,但是图片根本不会显示。
下面的代码是一个测试,这就是为什么它看起来如此'bad'。
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)。
在 JavaFX 中显示图像的最简单方法是使用 ImageView
。您可以创建单个 ImageView
并通过调用 setImage(...)
并传入 javafx.scene.image.Image
来更新其图像。我不知道您正在使用的相机 API:您可以直接生成 JavaFX 图像,在这种情况下,您的绘制框架方法看起来很简单:
private void drawFrame(Image image, ImageView imageView) {
imageView.setImage(image);
}
如果你只能生成BufferedImage
s,你可以做
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
方法。
标题好像有点乱,不过我会一一解释的。
我正在开发一个项目,我在 JPanel Java Swing 中显示网络摄像头捕获的图像。现在我必须将其与 JavaFx 集成。 我有一个控制器,其中有方法 startRecording,它会初始化 cameraThread 并告诉 class Camera 开始记录,在 Camera class 里面有一个方法 DrawFrame(BufferedImage, JPanel panel) 我调用来自 OpenCV 的函数 drawImage 在面板中绘制:
控制器:
public void startRecording(){
cameraInstance.setCameraRGBPanel(windowsInstance.getCameraRGBPanel());
cameraInstance.setCameraHSVPanel(windowsInstance.getCameraHSVPanel());
cameraInstance.setCameraThresholdPanel(windowsInstance.getCameraThresholdPanel());
cameraInstance.setRecord(true);
cameraThread = new Thread(cameraInstance);
cameraThread.start();
}
Class 相机:
private void drawFrame(BufferedImage buff, JPanel pane){
pane.getGraphics().drawImage(buff, 0, 0, null);
}
首先,JavaFX 没有 JPanel,Pane(一个选项)也没有 getGraphics,我尝试使用 SwingNode,添加 JPanel,然后照常执行所有操作,但是图片根本不会显示。
下面的代码是一个测试,这就是为什么它看起来如此'bad'。
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)。
在 JavaFX 中显示图像的最简单方法是使用 ImageView
。您可以创建单个 ImageView
并通过调用 setImage(...)
并传入 javafx.scene.image.Image
来更新其图像。我不知道您正在使用的相机 API:您可以直接生成 JavaFX 图像,在这种情况下,您的绘制框架方法看起来很简单:
private void drawFrame(Image image, ImageView imageView) {
imageView.setImage(image);
}
如果你只能生成BufferedImage
s,你可以做
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
方法。