gpt4 book ai didi

JavaFX Canvas 未绘制图像

转载 作者:行者123 更新时间:2023-11-30 08:36:30 29 4
gpt4 key购买 nike

我正在尝试从网络摄像头获取输入并将其绘制在 Canvas 上。

为此,我编写了以下代码块:

void addImageToCanvas(Image img){
GraphicsContext gc = canvas.getGraphicsContext2D();
gc.drawImage(img, 0, 0, canvas.getWidth(), canvas.getHeight());
}

如果我只在该函数中手动传递一个图像,它就可以工作。

如果我传递两个 Image,那么它只会绘制最后一个。

但我正在实现线程并从线程中不断调用它。然后函数就停在了线上:

gc.drawImage(img, 0, 0, canvas.getWidth(), canvas.getHeight());

调用方法的代码部分:

public void run() {

try {
FrameGrabber grabber = new VideoInputFrameGrabber(cameraId);

CvMemStorage storage = CvMemStorage.create();
grabber.start();

IplImage grabbedImage;
BufferedImage bufImg;
int counter = 0;
while (primaryCameraChosen != null) {
grabbedImage = grabber.grab();
bufImg = grabbedImage.getBufferedImage();
addImageToCanvas(SwingFXUtils.toFXImage(bufImg, null));
try{
Thread.sleep(10000);
} catch(InterruptedException e){}
}
grabber.stop();
grabber.release();
} catch (Exception ex) {
}
}

你能告诉我我做错了什么吗?解决办法是什么?谢谢。

最佳答案

所以你实际上有两个问题

1) If I pass two Images then it only draws the last one.

您正在将图像绘制到相同的 X、Y 坐标,具有相同的高度和宽度。结果是(就像在现实生活中,如果你在现有的画作上画东西一样)只有最后一幅画是可见的,因为它隐藏了第一幅画。这是预期的工作。

OP 发表评论后更新:

这一行的问题:gc.drawImage(img, 0, 0, canvas.getWidth(), canvas.getHeight()); 是,在第一个 Image 它尝试使用 Canvas 的实际高度和宽度绘制 Image,但此时 Canvas 本身很可能是未绘制,因此实际高度和宽度均为零,因此绘制的图片宽度和高度为零。

两种可能的解决方案是:

1) 只有在包含 CanvasStage 实际显示时才启动 Thread。这将确保 Canvas 即使在第一张图片中也具有正确的高度和宽度。

2) 监听 Canvas 的宽度和高度变化,并在需要时重绘 Image。这将确保,每当调整 Canvas 大小时,Image 都会重新绘制(它的优点是图片始终适合屏幕,因此这是建议的方法)

该示例包含这两种方法。

2) But I am implementing thread and calling it continuously from the thread. The function is then comes to stand still on the line

我们将看到完整的代码可能有什么问题,但是在您更新帖子以包括检测问题所需的每个部分之前,这里是一个使用 Image 更新 Canvas 的示例每 3 秒从后台线程:

public class Main extends Application {

Canvas canvas;

@Override
public void start(Stage primaryStage) {
try {
BorderPane root = new BorderPane();
Scene scene = new Scene(root,400,400);

canvas = new Canvas();

Pane pane = new Pane();
pane.getChildren().add(canvas);
canvas.widthProperty().bind(pane.widthProperty());
canvas.heightProperty().bind(pane.heightProperty());
root.setCenter(pane);


Thread thread = new Thread(new Runnable() {

private ObjectProperty<Image> imageToBeDrawn = new SimpleObjectProperty<Image>(new Image(getClass().getResource("a.jpg").toExternalForm()));

@Override
public void run() {

// Option 2: Listen to the width and height property change of the canvas and redraw the image
canvas.widthProperty().addListener(event -> addImageToCanvas(imageToBeDrawn.get()));
canvas.heightProperty().addListener(event -> addImageToCanvas(imageToBeDrawn.get()));

imageToBeDrawn.addListener(event -> addImageToCanvas(imageToBeDrawn.get()));

while(true){

Random rand = new Random();
if(rand.nextBoolean())
imageToBeDrawn.set(new Image(getClass().getResource("a.jpg").toExternalForm()));
else
imageToBeDrawn.set(new Image(getClass().getResource("b.jpg").toExternalForm()));

try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});

thread.setDaemon(true);
thread.start();

primaryStage.setScene(scene);

// Option 2: start the Thread only when the stage is showing
// primaryStage.showingProperty().addListener(new ChangeListener<Boolean>() {
//
// @Override
// public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
// if(newValue)
// thread.start();
//
// }
// });

primaryStage.show();



} catch(Exception e) {
e.printStackTrace();
}
}

void addImageToCanvas(Image img){
Platform.runLater(new Runnable(){

@Override
public void run() {

GraphicsContext gc = canvas.getGraphicsContext2D();
gc.drawImage(img, 0, 0, canvas.getWidth(), canvas.getHeight());
}});
}

public static void main(String[] args) {
launch(args);
}
}

关于JavaFX Canvas 未绘制图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37695834/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com