I am building a application which can show live feed from my webcam. So I have been searching for sample codes as there was no webcam support in JavaFX and finally I found the code (javaFX+ OpenCV). But I am using fxml for my application and the sample code I found is a Non-Fxml.
The following code is the sample code which I am not able to break it into FXML and its controller From here I find 2 ways 1:To break the non-fxml code 2:To use the non-fxml sample code in my application. So is it possible to use the non-FXML java code with the FXML application? or is there any other way?
For those who require webcam support in javaFX this snippet works perfectly fine. The only requirement is OPENCV libraries. Though I cannot take credit for the code. Thank You in advance
package test;
import java.io.ByteArrayInputStream;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.image.Image;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.videoio.VideoCapture;
public class Camera2 extends Application {
public static void main(String[] args) {
launch(args);
}
private static final int SCENE_W = 640;
private static final int SCENE_H = 480;
VideoCapture videoCapture;
Canvas canvas;
GraphicsContext g2d;
Stage stage;
AnimationTimer timer;
@Override
public void start(Stage stage) {
this.stage = stage;
initOpenCv();
canvas = new Canvas(SCENE_W, SCENE_H);
g2d = canvas.getGraphicsContext2D();
g2d.setStroke(Color.GREEN);
Group group = new Group(canvas);
Scene scene = new Scene(group, SCENE_W, SCENE_H);
stage.setScene(scene);
stage.setResizable(false);
stage.show();
timer = new AnimationTimer() {
Mat mat = new Mat();
@Override
public void handle(long now) {
videoCapture.read(mat);
Image image = mat2Image(mat);
g2d.drawImage(image, 0, 0);
}
};
timer.start();
}
private void initOpenCv() {
//setLibraryPath();
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
videoCapture = new VideoCapture();
videoCapture.open(0);
System.out.println("Camera open: " + videoCapture.isOpened());
stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
public void handle(WindowEvent we) {
timer.stop();
videoCapture.release();
System.out.println("Camera released");
}
});
}
public static Image mat2Image(Mat mat) {
MatOfByte buffer = new MatOfByte();
Imgcodecs.imencode(".png", mat, buffer);
return new Image(new ByteArrayInputStream(buffer.toArray()));
}
}
I tried using the above code in mycontroller file
public class FXMLDocumentController implements Initializable {
@FXML
private Canvas canvas;
@FXML
private Button button_start;
private static final int SCENE_W = 640;
private static final int SCENE_H = 480;
VideoCapture videoCapture;
GraphicsContext g2d;
Stage stage;
AnimationTimer timer;
@FXML
private void handleButtonAction(ActionEvent event) {
}
@Override
public void initialize(URL url, ResourceBundle rb) {
// this.stage = stage;
initOpenCv();
canvas = new Canvas(SCENE_W, SCENE_H);
g2d = canvas.getGraphicsContext2D();
g2d.setStroke(Color.GREEN);
Group group = new Group(canvas);
Scene scene = new Scene(group, SCENE_W, SCENE_H);
stage.setScene(scene);
stage.setResizable(false);
stage.show();
timer = new AnimationTimer() {
Mat mat = new Mat();
@Override
public void handle(long now) {
videoCapture.read(mat);
Image image = mat2Image(mat);
g2d.drawImage(image, 0, 0);
}
};
timer.start();
}
private void initOpenCv() {
//setLibraryPath();
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
videoCapture = new VideoCapture();
videoCapture.open(0);
System.out.println("Camera open: " + videoCapture.isOpened());
stage.setOnCloseRequest((WindowEvent we) -> {
timer.stop();
videoCapture.release();
System.out.println("Camera released");
});
}
But I got the following error
Exception in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$155(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:745)
Caused by: javafx.fxml.LoadException:
file:/home/anurag/NetBeansProjects/Test2/dist/run1986258874/Test2.jar!/test2/FXMLDocument.fxml
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2579)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3214)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)
at test2.Test2.start(Test2.java:22)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at com.sun.glass.ui.gtk.GtkApplication.lambda$null$49(GtkApplication.java:139)
... 1 more
Caused by: java.lang.NullPointerException
at test2.FXMLDocumentController.initOpenCv(FXMLDocumentController.java:104)
at test2.FXMLDocumentController.initialize(FXMLDocumentController.java:61)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2548)
... 17 more
Exception running application test2.Test2