0

I can't redraw imageview in while. Without while is work with single image. May be it will be work if i try to use diffrent thread for image redraw, but i don't kno how to make it. Anybody can give me example for way where i can make it workable^)

package videostepone;

import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.ByteArrayInputStream;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.core.Scalar;
import org.opencv.highgui.Highgui;
import org.opencv.highgui.VideoCapture;
import org.opencv.objdetect.CascadeClassifier;

/**
 *
 * @author Анютка
 */
public class FXMLDocumentController implements Initializable {

    @FXML
    private Label label;

    @FXML
    private ImageView imageCam1;

    @FXML
    private void handleButtonAction(ActionEvent event) throws InterruptedException {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        //System.loadLibrary("opencv_java2410");

        System.out.println("You clicked me!");
        label.setText("Hello World!");

        WebCamLive();
    }

    // Делает снимок с веб-камеры
    private void WebCamShot() throws InterruptedException
    {
        VideoCapture camera = new VideoCapture(0);
        Thread.sleep(1000);
        camera.open(0); //Useless
        if(!camera.isOpened()){
            System.out.println("Camera Error");
        }
        else{
            System.out.println("Camera OK?");
        }

        Mat frame = new Mat();
        camera.read(frame);

        System.out.println("Captured Frame Width " + frame.width());
        Highgui.imwrite("camera.jpg", frame);

        System.out.println("OK");
    }

    // Видео с веб-камеры
    private void WebCamLive() throws InterruptedException
    {
        int i = 0;
        VideoCapture camera = new VideoCapture(0);
        Thread.sleep(1000);
        camera.open(0); //Useless
        if(!camera.isOpened()){
            System.out.println("Camera Error");
        }
        else{
            System.out.println("Camera OK?");
        }

        Mat frame = new Mat();

        CascadeClassifier faceDetect = new CascadeClassifier("./res/haarcascade_frontalface_default.xml");


        while (true)
        {
            camera.read(frame);
            if (!frame.empty())
            {
                setImageOn(matToImage(frame));

//                label.setText("1");
//                Thread.sleep(6000);
//                label.setText("-");
                System.out.println(i++);
            }
        }
    }

    @FXML
    private void setImageOn(Image img)
    {
        imageCam1.setImage(img);
    }

    private Image matToImage(Mat m){
        MatOfByte memory = new MatOfByte();
        try {
            Highgui.imencode(".jpg", m, memory);
            return (new Image(new ByteArrayInputStream(memory.toArray())));
        } catch (Exception e) {
            System.out.println(e);
        }
        return (new Image(new ByteArrayInputStream(memory.toArray())));
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO
    }    

}
  • 1
    Your `while` loop runs infinitely without letting the JavaFX application thread paint anything on the screen. You shouldn't have infinitely running threads on your Application thread. – ItachiUchiha Dec 17 '14 at 12:40
  • my thread must be in other class? not in controller? Work with elements i can from controller, how i can setImage on scene? – Кукушка Dec 17 '14 at 14:19

1 Answers1

0

As ItachiUchiha has pointed out your controller has some threading problems. Like most other GUI toolkits, JavaFX is a single threaded GUI toolkit and thus all time consuming tasks which might block the GUI Thread should be performed elsewhere. Ohterwise nothings gets painted.

If I read your code correctly WebCamLive() takes a snapshot of the webcam every second? Now you have two options on how to do this with JavaFX:

  1. If the snapshot is taken rather fast, you can do this with a TimeLine, as shown here: Javafx Not on fx application thread when using timer
  2. If the snapshot takes some time to capture, I would recommend writing a ScheduledService.

For further information on threading in JavaFX refer to the tutorial here: http://docs.oracle.com/javafx/2/threads/jfxpub-threads.htm

Community
  • 1
  • 1
eckig
  • 10,964
  • 4
  • 38
  • 52
  • Ok. I can't understand: in javafx redraw is impossible task? Or i can make scene? that may have own thread and show me redrawing image video? – Кукушка Dec 18 '14 at 11:22
  • Of course you can "redraw", but you can (or better should) not block the UI Thread. I outlined two possible solutions in my answer.. – eckig Dec 18 '14 at 13:00