koifish082
9/24/2018 - 7:37 AM

Task will remain in background task

package presentation.controller;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.ResourceBundle;
import java.util.concurrent.atomic.AtomicReference;
import javafx.application.Platform;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.concurrent.Task;
import javafx.embed.swing.SwingFXUtils;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import com.github.sarxos.webcam.Webcam;
import javax.imageio.ImageIO;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.StackPane;
import javafx.stage.WindowEvent;
import presentation.MainApp;
import presentation.utils.FileUtil;


/**
 * This is controller for WebCamPreview FXML.
 */
public class WebCamPreviewController  extends BaseController implements Initializable {

    @FXML
    public StackPane stackPaneWebCamPage;

    @FXML
    public Button btnTakePhoto;

    @FXML
    public StackPane bpWebCamPaneHolder;

    @FXML
    public ImageView imgWebCamCapturedImage;

    private WebCamInfo webCamInfo;

    private class WebCamInfo {

        private String webCamName;

        private int webCamIndex;

        public String getWebCamName() {
            return webCamName;
        }

        public void setWebCamName(String webCamName) {
            this.webCamName = webCamName;
        }

        public int getWebCamIndex() {
            return webCamIndex;
        }

        public void setWebCamIndex(int webCamIndex) {
            this.webCamIndex = webCamIndex;
        }

        @Override
        public String toString() {
            return webCamName;
        }
    }

    private boolean cameraStop = false;
    private BufferedImage grabbedImage;
    private Webcam selWebCam = null;
    private ObjectProperty<Image> imageProperty = new SimpleObjectProperty<>();
    private FileUtil fileUtil;
    private final String TMP_IMAGE_NAME = "image%s.png";

    public WebCamPreviewController() {
        this.fileUtil = new FileUtil();
    }

    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {
        setUp();
    }

    public void setUp() {
        btnTakePhoto.setVisible(false);
        webCamInfo = new WebCamInfo();
        webCamInfo.setWebCamIndex(0);
        Task<Void> task = new Task<Void>() {
            @Override
            protected Void call() throws Exception {
                starWebCam(webCamInfo.getWebCamIndex());
                return null;
            }
        };
        Thread th = new Thread(task);
        th.setDaemon(true);
        th.start();

        MainApp.primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
            @Override
            public void handle(WindowEvent t) {
                Task<Void> task = new Task<Void>() {
                    @Override
                    protected Void call() throws Exception {
                        closeCamera();
                        return null;
                    }
                };
                Thread th = new Thread(task);
                th.setDaemon(true);
                th.start();
            }
        });
    }

    private void starWebCam(final int webCamIndex) {
        initializeWebCam(webCamIndex);
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                setImageViewSize();
            }
        });
    }

    private void setImageViewSize() {
        double height = bpWebCamPaneHolder.getHeight();
        double width = bpWebCamPaneHolder.getWidth();
        imgWebCamCapturedImage.setFitHeight(height);
        imgWebCamCapturedImage.setFitWidth(width);
        imgWebCamCapturedImage.prefHeight(height);
        imgWebCamCapturedImage.prefWidth(width);
        imgWebCamCapturedImage.setPreserveRatio(true);
    }

    private void initializeWebCam(final int webCamIndex) {
        if (selWebCam != null) {
            closeCamera();
        }
        selWebCam = Webcam.getWebcams().get(webCamIndex);
        selWebCam.setViewSize(new Dimension(640,480));
        selWebCam.open();

        startWebCamStream();
    }

    private void startWebCamStream() {
        cameraStop = false;
        btnTakePhoto.setVisible(true);

        Task<Void> webCamStreamTask = new Task<Void>() {
            @Override
            protected Void call() throws Exception {

                final AtomicReference<WritableImage> ref = new AtomicReference<>();
                while (!cameraStop) {
                    try {
                        if ((grabbedImage = selWebCam.getImage()) != null) {
                            Platform.runLater(new Runnable() {
                                @Override
                                public void run() {
                                    final Image mainImage = SwingFXUtils.toFXImage(grabbedImage, null);
                                    imageProperty.set(mainImage);
                                }
                            });
                            grabbedImage.flush();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                return null;
            }
        };
        Thread th = new Thread(webCamStreamTask);
        th.setDaemon(true);
        th.start();
        imgWebCamCapturedImage.imageProperty().bind(imageProperty);
        imgWebCamCapturedImage.setVisible(true);
    }

    private void closeCamera() {
        cameraStop = true;
        Webcam.getDiscoveryService().stop();
        selWebCam.close();
    }

    public void takePhotoBtn(ActionEvent event) {
        Task<Void> task = new Task<Void>() {
            @Override
            protected Void call() throws Exception {
                takePhoto();
                return null;
            }
        };
        Thread th = new Thread(task);
        th.setDaemon(true);
        th.start();
    }

    private void takePhoto() {
        btnTakePhoto.setVisible(false);
        fileUtil.makeTmpDir();
        try {
            ArrayList<String> imageNames = new ArrayList<>();
            for (int i = 1; i <= 15; i++) {
                BufferedImage image = selWebCam.getImage();
                String saveImagePath = buildSavingImagePath(i);
                ImageIO.write(image, "PNG", new File(saveImagePath));
                imageNames.add(buildSaveImageName(i));
            }
            fileUtil.createImageZip(imageNames);
        } catch(IOException e) {
            e.printStackTrace();
        }
        closeCamera();
    }

    private String buildSavingImagePath(int index) {
        return FileUtil.TMP_DIR_NAME + "/" + buildSaveImageName(index);
    }

    private String buildSaveImageName(int index) {
        return String.format(TMP_IMAGE_NAME, index);
    }
}
package presentation.navigator;

import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import presentation.utils.ResourceBundleUtf8Control;
import presentation.utils.config.Config;
import java.net.URL;
import java.io.IOException;
import java.util.Locale;
import java.util.ResourceBundle;

public class VitalBitMenuNavigator {

    private void launchNewScene(Stage stage, String fxmlName) {
        try {
            URL location = getClass().getResource("/fxml/" + fxmlName);
            ResourceBundle resources = ResourceBundle.getBundle("properties.string", Locale.getDefault(), new ResourceBundleUtf8Control());
            Parent root = FXMLLoader.load(location, resources);
            Scene scene = new Scene(root);
            stage.setScene(scene);
            stage.setTitle(Config.loadString("string.title"));
            stage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void launchWebCamPreviewStage(Stage stage) {
        launchNewScene(stage, "web_cam_preview.fxml");
    }
}
package presentation.controller;

import javafx.event.ActionEvent;
import javafx.fxml.Initializable;
import presentation.MainApp;
import presentation.navigator.MenuNavigator;

public class MenuController extends BaseController implements Initializable {

    protected MenuNavigator navigator;

    public MenuController() {
        navigator = new MenuNavigator();
    }

    public void launchWebCamPreview(ActionEvent actionEvent) {
        navigator.launchWebCamPreview(MainApp.primaryStage);
    }
}
package presentation;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.stage.Stage;
import presentation.navigator.MenuNavigator;

public class MainApp extends Application {

    public static Stage primaryStage;

    private MenuNavigator navigator;

    public MainApp() {
        navigator = new MenuNavigator();
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        MainApp.primaryStage = primaryStage;
        navigator.launchMenuStage(primaryStage);
    }

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