Javafx如何在另一个场景中的ImageView中显示从网络摄像机捕获的图像

时间:2018-07-02 03:15:09

标签: javafx

我有这个fxml布局。当我点击拍照时,它会打开一个屏幕供我使用网络摄像头拍照

enter image description here

对话框布局以从网络摄像头拍摄照片

enter image description here

我希望在网络摄像头上捕获的图片替换拍摄按钮旁边的fxml布局上的虚拟图像。这是我的文件: 包含虚拟图像和拍照按钮的FXML布局

<HBox prefHeight="79.0" prefWidth="232.0" spacing="30.0">
   <children>
      <VBox prefHeight="100.0" prefWidth="100.0">
         <children>
            <ImageView fx:id="profilePic" fitHeight="99.0" fitWidth="118.0" nodeOrientation="INHERIT" pickOnBounds="true">
               <image>
                  <Image url="@../images/profile_photo.png" />
               </image>
            </ImageView>
         </children>
      </VBox>
      <VBox prefHeight="200.0" prefWidth="100.0">
         <children>
            <Button mnemonicParsing="false" onAction="#takePhoto" text="Take Photo">
               <font>
                  <Font size="13.0" />
               </font>
               <VBox.margin>
                  <Insets bottom="20.0" top="10.0" />
               </VBox.margin>
            </Button>
            <Button mnemonicParsing="false" onAction="#pickPhoto" prefHeight="31.0" prefWidth="85.0" text="Upload &#10; ">
               <font>
                  <Font size="13.0" />
               </font>
               <VBox.margin>
                  <Insets bottom="10.0" />
               </VBox.margin></Button>
         </children>
      </VBox>
   </children>
</HBox>

FXML布局的控制器

public class AddParentController implements Initializable {


    @Override
    public void initialize(URL location, ResourceBundle resources) {

    }

    public void doAll(){
        ImageSelection.getImageSelectionInstance().imageProperty()
                .addListener((obs, oldImage, newImage) -> profilePic.setImage(newImage));
    }


    public void takePhoto(){
        try {
            Stage dialogStage = new Stage(StageStyle.UNDECORATED);
            BorderPane root = FXMLLoader.load(getClass().getResource("../views/WebCamPreview.fxml"));
            Scene scene = new Scene(root, 850, 390);
            dialogStage.setUserData("fromAddParent");
            dialogStage.initModality(Modality.APPLICATION_MODAL);
            dialogStage.setScene(scene);
            dialogStage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

包含WebCam预览的对话框布局

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.FlowPane?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.text.Font?>

<BorderPane prefHeight="390.0" prefWidth="850.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.controllers.WebCamPreviewController">
    <!-- TODO Add Nodes -->
    <bottom>
        <FlowPane fx:id="fpBottomPane" alignment="CENTER" columnHalignment="CENTER" hgap="50.0" prefHeight="80.0" prefWidth="200.0" style="-fx-background-color:#ccc;">
            <children>
                <Button fx:id="btnStartCamera" focusTraversable="false" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#stopCamera" prefHeight="40.0" prefWidth="120.0" text="Capture">
                    <font>
                        <Font name="Segoe UI" size="18.0" fx:id="x1" />
                    </font>
                </Button>
                <Button fx:id="btnProceedCamera" focusTraversable="false" font="$x1" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#proceed" prefHeight="40.0" prefWidth="120.0" text="Proceed" />
                <Button fx:id="btnResetCamera" focusTraversable="false" font="$x1" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#startCamera" prefHeight="40.0" prefWidth="120.0" text="Reset" />
                <Button fx:id="btnDisposeCamera" focusTraversable="false" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#disposeCamera" prefHeight="40.0" prefWidth="120.0" text="Close">
               <font>
                  <Font name="Segoe UI" size="18.0" fx:id="x11" />
               </font>
            </Button>
            </children>
        </FlowPane>
    </bottom>
    <center>
        <BorderPane fx:id="bpWebCamPaneHolder" prefHeight="200.0" prefWidth="200.0">
            <center>
                <ImageView fx:id="imgWebCamCapturedImage" fitHeight="150.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true" BorderPane.alignment="CENTER" />
            </center></BorderPane>
    </center>
    <top>
        <GridPane minHeight="-Infinity" minWidth="-Infinity" prefHeight="80.0" style="-fx-background-color:#ccc;&#10;">
            <children>
                <Label text="Webcam Image Capture" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.rowIndex="0" GridPane.rowSpan="1" GridPane.valignment="CENTER" GridPane.vgrow="ALWAYS">
                    <font>
                        <Font name="Segoe UI" size="34.0" />
                    </font>
                    <GridPane.margin>
                        <Insets top="10.0" />
                    </GridPane.margin>
                </Label>
            </children>
            <columnConstraints>
                <ColumnConstraints hgrow="SOMETIMES" maxWidth="795.0" minWidth="10.0" prefWidth="418.0" />
                <ColumnConstraints hgrow="SOMETIMES" maxWidth="502.0" minWidth="10.0" prefWidth="482.0" />
            </columnConstraints>
            <rowConstraints>
                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
            </rowConstraints>
        </GridPane>
    </top>
</BorderPane>

WebCam预览控制器

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.net.URL;
import java.util.ResourceBundle;
import com.github.sarxos.webcam.WebcamPanel;
import javafx.application.Platform;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.embed.swing.SwingFXUtils;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;  
import com.github.sarxos.webcam.Webcam;
import javafx.stage.Stage;

public class WebCamPreviewController implements Initializable {


    @FXML Button btnStartCamera;
    @FXML Button btnProceedCamera;
    @FXML Button btnDisposeCamera,btnResetCamera;
    @FXML BorderPane bpWebCamPaneHolder;
    @FXML FlowPane fpBottomPane;
    @FXML ImageView imgWebCamCapturedImage;
    private BufferedImage grabbedImage;
    private WebcamPanel selWebCamPanel = null;
    private Webcam selWebCam = null;
    private boolean stopCamera = false;
    private ObjectProperty<Image> imageProperty = new SimpleObjectProperty<Image>();
    Image mainiamge;
    private String userData;

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

        fpBottomPane.setDisable(true);

        try{
            initializeWebCam(0);
        }catch(Exception e){
            e.printStackTrace();
        }

        Platform.runLater(() -> {
            userData = (String) fpBottomPane.getScene().getWindow().getUserData();
            setImageViewSize();
        });

    }
    protected 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);

    }
    protected void initializeWebCam(final int webCamIndex) {

        Task<Void> webCamIntilizer = new Task<Void>() {

            @Override
            protected Void call() throws Exception {

                if(selWebCam == null)
                {
                    selWebCam = Webcam.getWebcams().get(webCamIndex);
                    selWebCam.open();
                }else
                {
                    closeCamera();
                    selWebCam = Webcam.getWebcams().get(webCamIndex);
                    selWebCam.open();

                }
                startWebCamStream();
                return null;
            }

        };

        new Thread(webCamIntilizer).start();
        fpBottomPane.setDisable(false);
        btnProceedCamera.setDisable(true);
        btnResetCamera.setDisable(true);
    }

    protected void startWebCamStream() {

        stopCamera  = false;
        Task<Void> task = new Task<Void>() {


            @Override
            protected Void call() throws Exception {

                while (!stopCamera) {
                    try {
                        if ((grabbedImage = selWebCam.getImage()) != null) {

                            Platform.runLater(new Runnable() {
                                @Override
                                public void run() {
                                        mainiamge = SwingFXUtils
                                            .toFXImage(grabbedImage, null);
                                    imageProperty.set(mainiamge);
                                }
                            });

                           grabbedImage.flush();

                        }
                    } catch (Exception e) {
                    } finally {

                    }

                }

                return null;

            }

        };
        Thread th = new Thread(task);
        th.setDaemon(true);
        th.start();
        imgWebCamCapturedImage.imageProperty().bind(imageProperty);

    }

    private void closeStage() {
        ((Stage) fpBottomPane.getScene().getWindow()).close();
    }

    private void closeCamera()
    {
        if(selWebCam != null)
        {
            selWebCam.close();
        }
    }

    public void proceed(){
        ImageSelection.getImageSelectionInstance().setImage(imgWebCamCapturedImage.getImage());
        AddParentController apc = new AddParentController();
        apc.doAll();
        closeStage();
    }

    public void proceedToAddPartner(){

    }

    public void stopCamera(ActionEvent event)
    {
        stopCamera = true;
        btnStartCamera.setDisable(true);
        btnResetCamera.setDisable(false);
        btnProceedCamera.setDisable(false);
    }

    public void startCamera(ActionEvent event)
    {
        stopCamera = false;
        startWebCamStream();
        btnStartCamera.setDisable(false);
        btnResetCamera.setDisable(true);
        btnProceedCamera.setDisable(true);
    }

    public void disposeCamera(ActionEvent event)
    {
        //stopCamera = true;
        //closeCamera();
        //Webcam.shutdown();
        //btnStopCamera.setDisable(true);
        //btnStartCamera.setDisable(true);
        closeStage();
    }


}

图片模型

import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.image.Image;

public class ImageSelection {

    private final ObjectProperty<Image> image = new SimpleObjectProperty<>();

    private static ImageSelection imageSelectionInstance= new ImageSelection();

    private ImageSelection(){}

    public static ImageSelection getImageSelectionInstance() {
        return imageSelectionInstance;
    }

    public ObjectProperty<Image> imageProperty() {
        return image ;
    }

    public final void setImage(Image image) {
        imageProperty().set(image);
    }

    public final Image getImage()
    {
        return imageProperty().get();
    }

}

面临的挑战是使网络摄像头捕获的图像显示在AddParent FXML布局上的profilPic ImageView中。

0 个答案:

没有答案