我在java中使用Webcam Capture API来访问我的网络摄像头。 Webcam Capture API是基于Swing构建的,我知道,但是我想将Webcam Swing类与我的JavaFX类结合起来。 JavaFX类在屏幕上显示一个矩形。我的目标是:运行我的JavaFX类,在屏幕上显示矩形。在某些时候(例如鼠标点击)我想启动网络摄像头。网络摄像头设置为查看屏幕,然后应该使用矩形的图像做某些事情。
JavaFX类:
public class JavaFXDisplay extends Application {
@Override
public void start(Stage primaryStage) {
WebcamCapture wc = new WebcamCapture();
StackPane root = new StackPane();
Rectangle rectangle = new Rectangle();
rectangle.setWidth(500);
rectangle.setHeight(500);
Scene scene = new Scene(root, 1000, 1000);
root.getChildren().addAll(rectangle);
primaryStage.setScene(scene);
primaryStage.show();
scene.addEventFilter(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
wc.doSomething();
}
});
}
public static void main(String[] args) {
launch(args);
}
}
Swing课程:
public class WebcamCapture extends JFrame implements Runnable, ThreadFactory {
private static final long serialVersionUID = 6441489157408381878L;
private Executor executor = Executors.newSingleThreadExecutor(this);
private Webcam webcam = null;
private WebcamPanel panel = null;
private JTextArea textarea = null;
public WebcamCapture() {
super();
setLayout(new FlowLayout());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Dimension size = WebcamResolution.QVGA.getSize();
webcam = Webcam.getWebcams().get(0);
webcam.setViewSize(size);
panel = new WebcamPanel(webcam);
panel.setPreferredSize(size);
textarea = new JTextArea();
textarea.setEditable(false);
textarea.setPreferredSize(size);
add(panel);
add(textarea);
pack();
setVisible(true);
}
public void doSomething() {
executor.execute(this);
}
@Override
public void run() {
do {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
BufferedImage image = null;
if (webcam.isOpen()) {
if ((image = webcam.getImage()) == null) {
continue;
}
doSomeStuff;
}
} while (true);
}
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r, "example-runner");
t.setDaemon(true);
return t;
}
public static void main(String[] args) {
new WebcamCapture();
}
}
但是我的JavaFX类没有启动/显示。我的代码出了什么问题?
答案 0 :(得分:0)
我不熟悉你正在使用的网络摄像头API(所以我不知道这是否是唯一的错误),但你需要在AWT事件调度线程上创建你的Swing内容。目前,您正在FX应用程序线程上创建它。
您可以使用以下习语:
public class JavaFXDisplay extends Application {
private WebcamCapture wc ;
@Override
public void init() throws Exception {
super.init();
FutureTask<WebcamCapture> launchWebcam = new FutureTask<>(WebcamCapture::new) ;
SwingUtilities.invokeLater(launchWebcam);
// block until webcam is started:
wc = launchWebcam.get();
}
@Override
public void start(Stage primaryStage) throws Exception {
StackPane root = new StackPane();
Rectangle rectangle = new Rectangle();
rectangle.setWidth(500);
rectangle.setHeight(500);
Scene scene = new Scene(root, 1000, 1000);
root.getChildren().addAll(rectangle);
primaryStage.setScene(scene);
primaryStage.show();
scene.addEventFilter(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
wc.doSomething();
}
});
}
public static void main(String[] args) {
launch(args);
}
}
供参考,这是一个仅限JavaFX的网络摄像头查看器。我在运行OS X Sierra(10.12.2)的MacBookPro上进行了测试,配备了带有摄像头的2011年27“Thunderbolt显示器。
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import com.github.sarxos.webcam.Webcam;
import com.github.sarxos.webcam.WebcamResolution;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class FXWebCamViewer extends Application {
private BlockingQueue<Image> imageQueue = new ArrayBlockingQueue<>(5);
private Executor exec = Executors.newCachedThreadPool(runnable -> {
Thread t = new Thread(runnable);
t.setDaemon(true);
return t ;
});
private Webcam webcam;
@Override
public void init() {
webcam = Webcam.getWebcams().get(0);
Dimension viewSize = WebcamResolution.QVGA.getSize();
webcam.setViewSize(viewSize);
webcam.open();
}
@Override
public void start(Stage primaryStage) {
ImageView imageView = new ImageView();
StackPane root = new StackPane(imageView);
imageView.fitWidthProperty().bind(root.widthProperty());
imageView.fitHeightProperty().bind(root.heightProperty());
imageView.setPreserveRatio(true);
AnimationTimer updateImage = new AnimationTimer() {
@Override
public void handle(long timestamp) {
Image image = imageQueue.poll();
if (image != null) {
imageView.setImage(image);
}
}
};
updateImage.start();
exec.execute(this::generateImages);
Scene scene = new Scene(root, 600, 600);
primaryStage.setScene(scene);
primaryStage.show();
}
private void generateImages() {
while (! Thread.interrupted()) {
try {
if (webcam.isOpen() && webcam.isImageNew()) {
BufferedImage bimg = webcam.getImage();
if (bimg != null) {
imageQueue.put(SwingFXUtils.toFXImage(bimg, null));
}
} else {
Thread.sleep(250);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
public static void main(String[] args) {
launch(args);
}
}