Commit 21032025

This commit is contained in:
2025-03-21 14:24:05 +07:00
parent b248c59e32
commit 80d468a79a
37 changed files with 858 additions and 964 deletions

View File

@@ -3,63 +3,50 @@
<output-path>$PROJECT_DIR$/out/artifacts/ErhaCam_jar</output-path>
<root id="archive" name="ErhaCam.jar">
<element id="module-output" name="ErhaCam" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-fxml/21/javafx-fxml-21-win.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/xerial/sqlite-jdbc/3.46.0.0/sqlite-jdbc-3.46.0.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/controlsfx/controlsfx/11.2.1/controlsfx-11.2.1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-base/21/javafx-base-21.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/javacv-platform/1.5.10/javacv-platform-1.5.10.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/javacv/1.5.10/javacv-1.5.10.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/javacpp/1.5.10/javacpp-1.5.10.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/openblas/0.3.26-1.5.10/openblas-0.3.26-1.5.10.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/opencv/4.9.0-1.5.10/opencv-4.9.0-1.5.10.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/ffmpeg/6.1.1-1.5.10/ffmpeg-6.1.1-1.5.10.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/flycapture/2.13.3.31-1.5.9/flycapture-2.13.3.31-1.5.9.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/libdc1394/2.2.6-1.5.9/libdc1394-2.2.6-1.5.9.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/libfreenect/0.5.7-1.5.9/libfreenect-0.5.7-1.5.9.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/libfreenect2/0.2.0-1.5.9/libfreenect2-0.2.0-1.5.9.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/librealsense/1.12.4-1.5.9/librealsense-1.12.4-1.5.9.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/librealsense2/2.53.1-1.5.9/librealsense2-2.53.1-1.5.9.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/videoinput/0.200-1.5.9/videoinput-0.200-1.5.9.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/artoolkitplus/2.3.1-1.5.9/artoolkitplus-2.3.1-1.5.9.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/leptonica/1.84.1-1.5.10/leptonica-1.84.1-1.5.10.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/tesseract/5.3.4-1.5.10/tesseract-5.3.4-1.5.10.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/javacpp-platform/1.5.10/javacpp-platform-1.5.10.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/javacpp/1.5.10/javacpp-1.5.10-windows-x86_64.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/openblas-platform/0.3.26-1.5.10/openblas-platform-0.3.26-1.5.10.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/opencv-platform/4.9.0-1.5.10/opencv-platform-4.9.0-1.5.10.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/opencv/4.9.0-1.5.10/opencv-4.9.0-1.5.10-windows-x86_64.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/ffmpeg-platform/6.1.1-1.5.10/ffmpeg-platform-6.1.1-1.5.10.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/flycapture-platform/2.13.3.31-1.5.9/flycapture-platform-2.13.3.31-1.5.9.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/libdc1394-platform/2.2.6-1.5.9/libdc1394-platform-2.2.6-1.5.9.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/libfreenect-platform/0.5.7-1.5.9/libfreenect-platform-0.5.7-1.5.9.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/libfreenect2-platform/0.2.0-1.5.9/libfreenect2-platform-0.2.0-1.5.9.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/librealsense-platform/1.12.4-1.5.9/librealsense-platform-1.12.4-1.5.9.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/librealsense2-platform/2.53.1-1.5.9/librealsense2-platform-2.53.1-1.5.9.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/videoinput-platform/0.200-1.5.9/videoinput-platform-0.200-1.5.9.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/videoinput/0.200-1.5.9/videoinput-0.200-1.5.9-windows-x86_64.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/artoolkitplus-platform/2.3.1-1.5.9/artoolkitplus-platform-2.3.1-1.5.9.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/leptonica-platform/1.84.1-1.5.10/leptonica-platform-1.84.1-1.5.10.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/tesseract-platform/5.3.4-1.5.10/tesseract-platform-5.3.4-1.5.10.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/commons-net/commons-net/3.11.1/commons-net-3.11.1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/google/zxing/javase/3.5.3/javase-3.5.3.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/google/zxing/core/3.5.3/core-3.5.3.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/beust/jcommander/1.82/jcommander-1.82.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/github/jai-imageio/jai-imageio-core/1.4.0/jai-imageio-core-1.4.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/tinylog/tinylog-impl/2.7.0/tinylog-impl-2.7.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/tinylog/tinylog-api/2.7.0/tinylog-api-2.7.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-controls/21/javafx-controls-21.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-fxml/21/javafx-fxml-21.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-graphics/21/javafx-graphics-21-win.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/google/code/gson/gson/2.11.0/gson-2.11.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/google/errorprone/error_prone_annotations/2.27.0/error_prone_annotations-2.27.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-graphics/21/javafx-graphics-21.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-base/21/javafx-base-21-win.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/net/java/dev/jna/jna/5.15.0/jna-5.15.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/slf4j/slf4j-jcl/1.7.36/slf4j-jcl-1.7.36.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/javacpp/1.5.10/javacpp-1.5.10.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-controls/21/javafx-controls-21-win.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/tinylog/tinylog-impl/2.7.0/tinylog-impl-2.7.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/opencv/4.9.0-1.5.10/opencv-4.9.0-1.5.10-windows-x86_64.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/openblas/0.3.26-1.5.10/openblas-0.3.26-1.5.10-windows-x86_64.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/controlsfx/controlsfx/11.2.1/controlsfx-11.2.1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-base/21/javafx-base-21-win.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-fxml/21/javafx-fxml-21.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/openblas/0.3.26-1.5.10/openblas-0.3.26-1.5.10.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/videoinput/0.200-1.5.9/videoinput-0.200-1.5.9.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/google/zxing/javase/3.5.3/javase-3.5.3.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-controls/21/javafx-controls-21.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/net/java/dev/jna/jna/5.15.0/jna-5.15.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/leptonica/1.84.1-1.5.10/leptonica-1.84.1-1.5.10.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/projectlombok/lombok/1.18.30/lombok-1.18.30.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-graphics/21/javafx-graphics-21-win.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-graphics/21/javafx-graphics-21.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/libfreenect/0.5.7-1.5.9/libfreenect-0.5.7-1.5.9.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/github/jai-imageio/jai-imageio-core/1.4.0/jai-imageio-core-1.4.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/librealsense2/2.53.1-1.5.9/librealsense2-2.53.1-1.5.9.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-fxml/21/javafx-fxml-21-win.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/libfreenect2/0.2.0-1.5.9/libfreenect2-0.2.0-1.5.9.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/google/errorprone/error_prone_annotations/2.27.0/error_prone_annotations-2.27.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/xerial/sqlite-jdbc/3.46.0.0/sqlite-jdbc-3.46.0.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/google/code/gson/gson/2.11.0/gson-2.11.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/videoinput/0.200-1.5.9/videoinput-0.200-1.5.9-windows-x86_64.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-controls/21/javafx-controls-21-win.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/slf4j/slf4j-jcl/1.7.36/slf4j-jcl-1.7.36.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/opencv/4.9.0-1.5.10/opencv-4.9.0-1.5.10.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/javacv/1.5.10/javacv-1.5.10.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/google/zxing/core/3.5.3/core-3.5.3.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/librealsense/1.12.4-1.5.9/librealsense-1.12.4-1.5.9.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/flycapture/2.13.3.31-1.5.9/flycapture-2.13.3.31-1.5.9.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/tesseract/5.3.4-1.5.10/tesseract-5.3.4-1.5.10.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/beust/jcommander/1.82/jcommander-1.82.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/tinylog/tinylog-api/2.7.0/tinylog-api-2.7.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-base/21/javafx-base-21.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/ffmpeg/6.1.1-1.5.10/ffmpeg-6.1.1-1.5.10-windows-x86_64.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/ffmpeg/6.1.1-1.5.10/ffmpeg-6.1.1-1.5.10.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/javacpp/1.5.10/javacpp-1.5.10-windows-x86_64.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/artoolkitplus/2.3.1-1.5.9/artoolkitplus-2.3.1-1.5.9.jar" path-in-jar="/" />
</root>
</artifact>
</component>

View File

@@ -1,4 +1,4 @@
#Thu Feb 13 11:48:36 WIB 2025
#Mon Mar 17 15:01:40 WIB 2025
AudioPhase1=C\:\\Users\\rdkar\\OneDrive\\Documents\\IntelliJ Project\\ErhaCam\\audio\\phase1.mp3
AudioPhase2=C\:\\Users\\rdkar\\OneDrive\\Documents\\IntelliJ Project\\ErhaCam\\audio\\phase2.mp3
AudioPhase3=C\:\\Users\\rdkar\\OneDrive\\Documents\\IntelliJ Project\\ErhaCam\\audio\\phase3.mp3
@@ -11,7 +11,7 @@ CameraConfigLeft90={"Brightness"\:0.0,"Contrast"\:0.0,"Saturation"\:0.0,"Hue"\:0
CameraConfigRight45={"Brightness"\:0.0,"Contrast"\:0.0,"Saturation"\:0.0,"Hue"\:0.0,"Gain"\:1.0,"Exposure"\:1.0,"Sharpness"\:0.0,"Gamma"\:0.0,"AutoExposure"\:true,"AutoFocus"\:true,"AutoWhiteBalance"\:true}
CameraConfigRight90={"Brightness"\:0.0,"Contrast"\:0.0,"Saturation"\:0.0,"Hue"\:0.0,"Gain"\:1.0,"Exposure"\:1.0,"Sharpness"\:0.0,"Gamma"\:0.0,"AutoExposure"\:true,"AutoFocus"\:true,"AutoWhiteBalance"\:true}
CameraLeft45=
CameraLeft90=
CameraLeft90=ACER QHD User Facing
CameraRight45=
CameraRight90=
FTPHost=192.168.10.2
@@ -19,7 +19,7 @@ FTPPass=password
FTPPath=/
FTPPort=21
FTPUser=user
PhotoDirectory=C\:\\Users\\rdkar\\OneDrive\\Documents\\IntelliJ Project\\ErhaCam
PhotoDirectory=C\:\\Users\\rdkar\\OneDrive\\Desktop\\Erha Capture
cascadeMaxSize=500
cascadeMinNeighbors=3
cascadeMinSize=250

Binary file not shown.

Binary file not shown.

Binary file not shown.

144
pom.xml
View File

@@ -36,76 +36,81 @@
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.bytedeco</groupId>-->
<!-- <artifactId>javacv-platform</artifactId>-->
<!-- <version>1.5.10</version>-->
<!-- <exclusions>-->
<!-- <exclusion>-->
<!-- <groupId>org.bytedeco</groupId>-->
<!-- <artifactId>leptonica-platform</artifactId>-->
<!-- </exclusion>-->
<!-- <exclusion>-->
<!-- <groupId>org.bytedeco</groupId>-->
<!-- <artifactId>artoolkitplus-platform</artifactId>-->
<!-- </exclusion>-->
<!-- <exclusion>-->
<!-- <groupId>org.bytedeco</groupId>-->
<!-- <artifactId>libdc1394-platform</artifactId>-->
<!-- </exclusion>-->
<!-- <exclusion>-->
<!-- <groupId>org.bytedeco</groupId>-->
<!-- <artifactId>libfreenect-platform</artifactId>-->
<!-- </exclusion>-->
<!-- <exclusion>-->
<!-- <groupId>org.bytedeco</groupId>-->
<!-- <artifactId>libfreenect2-platform</artifactId>-->
<!-- </exclusion>-->
<!-- <exclusion>-->
<!-- <groupId>org.bytedeco</groupId>-->
<!-- <artifactId>flycapture-platform</artifactId>-->
<!-- </exclusion>-->
<!-- <exclusion>-->
<!-- <groupId>org.bytedeco</groupId>-->
<!-- <artifactId>librealsense-platform</artifactId>-->
<!-- </exclusion>-->
<!-- <exclusion>-->
<!-- <groupId>org.bytedeco</groupId>-->
<!-- <artifactId>librealsense2-platform</artifactId>-->
<!-- </exclusion>-->
<!-- <exclusion>-->
<!-- <groupId>org.bytedeco</groupId>-->
<!-- <artifactId>tesseract-platform</artifactId>-->
<!-- </exclusion>-->
<!-- &lt;!&ndash; platform dibuangin semua, kemudian tambah sendiri linux-arm64, windows-x86_64, linux-x86_64 &ndash;&gt;-->
<!-- <exclusion>-->
<!-- <groupId>org.bytedeco</groupId>-->
<!-- <artifactId>flandmark-platform</artifactId>-->
<!-- </exclusion>-->
<!-- <exclusion>-->
<!-- <groupId>org.bytedeco</groupId>-->
<!-- <artifactId>openblas-platform</artifactId>-->
<!-- </exclusion>-->
<!-- <exclusion>-->
<!-- <groupId>org.bytedeco</groupId>-->
<!-- <artifactId>ffmpeg-platform</artifactId>-->
<!-- </exclusion>-->
<!-- <exclusion>-->
<!-- <groupId>org.bytedeco</groupId>-->
<!-- <artifactId>videoinput-platform</artifactId>-->
<!-- </exclusion>-->
<!-- <exclusion>-->
<!-- <groupId>org.bytedeco</groupId>-->
<!-- <artifactId>javacpp-platform</artifactId>-->
<!-- </exclusion>-->
<!-- <exclusion>-->
<!-- <groupId>org.bytedeco</groupId>-->
<!-- <artifactId>opencv-platform</artifactId>-->
<!-- </exclusion>-->
<!-- </exclusions>-->
<!-- </dependency>-->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv-platform</artifactId>
<artifactId>javacv</artifactId>
<version>1.5.10</version>
<exclusions>
<exclusion>
<groupId>org.bytedeco</groupId>
<artifactId>leptonica-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco</groupId>
<artifactId>artoolkitplus-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco</groupId>
<artifactId>libdc1394-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco</groupId>
<artifactId>libfreenect-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco</groupId>
<artifactId>libfreenect2-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco</groupId>
<artifactId>flycapture-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco</groupId>
<artifactId>librealsense-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco</groupId>
<artifactId>librealsense2-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco</groupId>
<artifactId>tesseract-platform</artifactId>
</exclusion>
<!-- platform dibuangin semua, kemudian tambah sendiri linux-arm64, windows-x86_64, linux-x86_64 -->
<exclusion>
<groupId>org.bytedeco</groupId>
<artifactId>flandmark-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco</groupId>
<artifactId>openblas-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco</groupId>
<artifactId>ffmpeg-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco</groupId>
<artifactId>videoinput-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco</groupId>
<artifactId>javacpp-platform</artifactId>
</exclusion>
<exclusion>
<groupId>org.bytedeco</groupId>
<artifactId>opencv-platform</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
@@ -126,11 +131,6 @@
<version>4.9.0-1.5.10</version>
<classifier>windows-x86_64</classifier>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacpp</artifactId>
<version>1.5.10</version>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacpp</artifactId>

Binary file not shown.

Binary file not shown.

View File

@@ -724,11 +724,11 @@ public class ConfigFile {
private @Getter String ThumbsDirectory;
private void MakeDirectories(){
String FullQualityDirectory = Path.of(PhotoDirectory,"FullQuality").toString();
String FullQualityCropDirectory = Path.of(PhotoDirectory,"FullQualityCrop").toString();
String CompressedDirectory = Path.of(PhotoDirectory,"Compressed").toString();
String CompressedCropDirectory = Path.of(PhotoDirectory,"CompressedCrop").toString();
String ThumbsDirectory = Path.of(PhotoDirectory,"thumbs").toString();
FullQualityDirectory = Path.of(PhotoDirectory,"FullQuality").toString();
FullQualityCropDirectory = Path.of(PhotoDirectory,"FullQualityCrop").toString();
CompressedDirectory = Path.of(PhotoDirectory,"Compressed").toString();
CompressedCropDirectory = Path.of(PhotoDirectory,"CompressedCrop").toString();
ThumbsDirectory = Path.of(PhotoDirectory,"thumbs").toString();
MakeDirectory(FullQualityDirectory);
MakeDirectory(FullQualityCropDirectory);
MakeDirectory(CompressedDirectory);

View File

@@ -8,6 +8,7 @@ import javafx.scene.control.Alert;
import javafx.scene.image.Image;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.bytedeco.javacv.OpenCVFrameConverter;
import org.bytedeco.opencv.global.opencv_core;
import org.bytedeco.opencv.global.opencv_imgcodecs;
import org.bytedeco.opencv.global.opencv_imgproc;
import org.bytedeco.opencv.opencv_core.Mat;
@@ -29,6 +30,8 @@ import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import static org.bytedeco.opencv.global.opencv_core.CV_64F;
@SuppressWarnings("unused")
public class SomeCodes {
public final static String currentDirectory = System.getProperty("user.dir");
@@ -130,10 +133,6 @@ public class SomeCodes {
}
}
/**
* Make thumbfile from source jpg file
* @param sourcejpg source jpg file
@@ -516,6 +515,14 @@ public class SomeCodes {
return false;
}
public static void Print(String... x){
if (x!=null && x.length>0){
for(String xx : x){
System.out.println(xx);
}
}
}
/**
* Check if Region of Interest is inside UMat
* @param ROI Region of Interest
@@ -598,4 +605,50 @@ public class SomeCodes {
alert.showAndWait();
}
public static double CalculateSharpness(String filename){
if (ValidFile(filename)){
try(Mat mat = opencv_imgcodecs.imread(filename)){
return CalculateSharpness(new UMat(mat));
} catch (Exception e){
Logger.error("Error calculating sharpness: "+filename+", Msg : "+e.getMessage());
}
}
return 0;
}
public static double FindLowestValue(double... values){
if (values!=null && values.length>0){
double lowest = values[0];
for(double x : values){
if (x<lowest){
lowest = x;
}
}
return lowest;
}
return 0;
}
public static double CalculateSharpness(UMat mat){
if (mat!=null && !mat.empty()){
UMat gray = new UMat();
opencv_imgproc.cvtColor(mat, gray, opencv_imgproc.COLOR_BGR2GRAY);
UMat laplacian = new UMat();
opencv_imgproc.Laplacian(gray, laplacian, CV_64F);
UMat mean = new UMat(1,1, CV_64F);
UMat stddev = new UMat(1,1, CV_64F);
opencv_core.meanStdDev(laplacian, mean, stddev);
Mat _std = new Mat();
stddev.copyTo(_std);
return _std.ptr(0).getDouble() * _std.ptr(0).getDouble();
}
return 0;
}
public static boolean IsBlurred(UMat mat, double threshold){
return CalculateSharpness(mat)<threshold;
}
}

View File

@@ -67,6 +67,11 @@ public class PhotoReviewClass {
this.ThumbRight90 = ThumbRight90;
}
@Override
public String toString(){
return "id: "+id+"\r\nDateTime: "+DateTime+"\r\nPrefix: "+Prefix+"\r\nFileLeft90: "+FileLeft90+"\r\nFileLeft45: "+FileLeft45+"\r\nFileCenter: "+FileCenter+"\r\nFileRight45: "+FileRight45+"\r\nFileRight90: "+FileRight90+"\r\nThumbLeft90: "+ThumbLeft90+"\r\nThumbLeft45: "+ThumbLeft45+"\r\nThumbCenter: "+ThumbCenter+"\r\nThumbRight45: "+ThumbRight45+"\r\nThumbRight90: "+ThumbRight90;
}
/**
* Get all Full Resolution files that are not null
* @return array of files

View File

@@ -3,7 +3,6 @@ package Database;
import static Config.SomeCodes.LocalDateTimeToString;
import static Config.SomeCodes.ValidString;
import lombok.val;
import org.tinylog.Logger;
import java.sql.*;
@@ -41,6 +40,8 @@ public class Sqlite {
*/
public void Insert(PhotoReviewClass pr){
if (pr!=null){
// System.out.println("Inserting PhotoReviewClass");
// System.out.println(pr);
Insert(pr.getPrefix(), pr.getFileLeft90(), pr.getFileLeft45(), pr.getFileCenter(), pr.getFileRight45(), pr.getFileRight90(), pr.getThumbLeft90(), pr.getThumbLeft45(), pr.getThumbCenter(), pr.getThumbRight45(), pr.getThumbRight90());
}
}
@@ -107,6 +108,13 @@ public class Sqlite {
try{
Connection conn = GetConnection();
if (conn != null){
// System.out.println("Inserting data");
// System.out.println("prefix: "+prefix);
// System.out.println("fileLeft90: "+fileLeft90);
// System.out.println("fileLeft45: "+fileLeft45);
// System.out.println("fileCenter: "+fileCenter);
// System.out.println("fileRight45: "+fileRight45);
// System.out.println("fileRight90: "+fileRight90);
PreparedStatement stmt = conn.prepareStatement("INSERT INTO photos (DateTime, Prefix, FileLeft90, FileLeft45, FileCenter, FileRight45, FileRight90, ThumbLeft90, ThumbLeft45, ThumbCenter, ThumbRight45, ThumbRight90 ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
stmt.setString(1, LocalDateTimeToString(LocalDateTime.now()));

View File

@@ -3,6 +3,7 @@ package ErhaAPI;
import Config.SomeCodes;
import com.google.gson.Gson;
import lombok.Getter;
import org.tinylog.Logger;
import java.io.File;
@@ -29,6 +30,10 @@ public class ErhaAPI {
private final Gson gson = new Gson();
/**
* Create Erha API object
* @param isProduction if true will use Production URL, if false will use Staging URL
*/
public ErhaAPI(boolean isProduction){
final String API_URL_PROD = "https://connect-api.aryanoble.co.id/api";
final String API_URL_STAGING = "https://connect-api-staging.aryanoble.web.id/api";
@@ -39,6 +44,7 @@ public class ErhaAPI {
* Set API Username
* @param API_USERNAME API Username
*/
@SuppressWarnings("unused")
public void setAPI_USERNAME(String API_USERNAME){
if (ValidString(API_USERNAME)){
if (!API_USERNAME.equals(this.API_USERNAME)){
@@ -52,6 +58,7 @@ public class ErhaAPI {
* Set API Password
* @param API_PASSWORD API Password
*/
@SuppressWarnings("unused")
public void setAPI_PASSWORD(String API_PASSWORD){
if (ValidString(API_PASSWORD)){
if (!API_PASSWORD.equals(this.API_PASSWORD)){
@@ -66,7 +73,7 @@ public class ErhaAPI {
* @param Barcode Barcode to verify
* @return BarcodeResullt object if success, or null if failed
*/
public BarcodeResullt Validate_Barcode(String Barcode){
public BarcodeResullt Validate_Barcode(String Barcode, boolean printdebug){
if (ValidBarCode(Barcode)){
try (HttpClient client = HttpClient.newHttpClient()) {
@@ -79,48 +86,30 @@ public class ErhaAPI {
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode()==200){
String body = response.body();
if (printdebug){
System.out.println("Validate_Barcode status code : " + response.statusCode());
System.out.println("Validate_Barcode HTTP body : ");
System.out.println(body);
}
return gson.fromJson(body, BarcodeResullt.class);
} else System.out.println("Validate Barcode status code : " + response.statusCode());
} else {
Logger.error("Validate_Barcode failed, status code : " , response.statusCode());
System.out.println("Validate Barcode status code : " + response.statusCode());
}
} catch (IOException e) {
System.out.println("Validate_Barcode IO Exception, Msg : " + e.getMessage());
Logger.error("Validate_Barcode IO Exception, Msg : " , e.getMessage());
} catch (InterruptedException e) {
System.out.println("Validate_Barcode Interrupted Exception, Msg : " + e.getMessage());
Logger.error("Validate_Barcode Interrupted Exception, Msg : " , e.getMessage());
}
}
return null;
}
// public String Upload_File_OKHttp(String patientID, String filename){
// if (ValidMedicalRecordId(patientID)){
// int medical_record_detail_id = toInt(patientID);
// if (ValidFile(filename)){
// try {
// okhttp3.OkHttpClient client = new okhttp3.OkHttpClient();
// okhttp3.RequestBody requestBody = new okhttp3.MultipartBody.Builder()
// .setType(okhttp3.MultipartBody.FORM)
// .addFormDataPart("medical_record_detail_id", String.valueOf(medical_record_detail_id))
// .addFormDataPart("file", filename, okhttp3.RequestBody.create(okhttp3.MediaType.parse("application/octet-stream"), new java.io.File(filename)))
// .build();
//
// okhttp3.Request request = new okhttp3.Request.Builder()
// .url(API_URL + "/photobooth/photobooth")
// .header("Authorization", "Basic " + auth)
// .post(requestBody)
// .build();
//
// okhttp3.Response response = client.newCall(request).execute();
// if (response.isSuccessful()){
// return response.body().string();
// } else System.out.println("Upload_File_OKHttp status code : " + response.code());
// } catch (Exception e){
// System.out.println("Upload_File_OKHttp Exception, Msg : " + e.getMessage());
// }
// } else return "Invalid File";
// } else return "Invalid Patient ID";
// return null;
// }
/**
@@ -129,7 +118,7 @@ public class ErhaAPI {
* @param filename File to upload
* @return null if failed, or response body if success
*/
public UploadResult Upload_File(String patientID, String filename) {
public UploadResult Upload_File(String patientID, String filename, boolean printdebug) {
if (ValidMedicalRecordId(patientID)){
int medical_record_detail_id = toInt(patientID);
if (ValidFile(filename)){
@@ -173,14 +162,25 @@ public class ErhaAPI {
// Send request
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (printdebug){
System.out.println("Upload_File status code : " + response.statusCode());
System.out.println("Upload_File HTTP body : ");
System.out.println(response.body());
}
if (response.statusCode()==200){
return gson.fromJson(response.body(), UploadResult.class);
} else System.out.println("Upload_File status code : " + response.statusCode());
} else {
System.out.println("Upload_File status code : " + response.statusCode());
Logger.error("Upload_File file ",filename," failed, status code : " , response.statusCode());
}
} catch (Exception e){
System.out.println("Upload_File Exception, Msg : " + e.getMessage());
Logger.error("Upload_File file ",filename," failed, Exception, Msg : " , e.getMessage());
}
}
}

View File

@@ -14,6 +14,7 @@ public class PhotoResult {
private String thumbnail;
private Rect BestROI;
private Rect ReducedROI;
private double sharpscore;
public PhotoResult(String cameraname){
this.cameraname = cameraname;
this.fullres = "";

View File

@@ -0,0 +1,99 @@
package id.co.gtc.erhacam;
import javafx.animation.PauseTransition;
import javafx.application.Platform;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.util.Duration;
import java.util.Optional;
public class AutoCloseAlert {
private static Stage currentAlertStage;
public static String shownTitle = "";
public static String shownContent = "";
public static String shownHeader = "";
private static void clear(){
shownTitle = "";
shownContent = "";
shownHeader = "";
}
/**
* Close the current alert if it is shown
*/
public static void close(){
Optional.ofNullable(currentAlertStage).ifPresent(Stage::close);
currentAlertStage = null;
clear();
}
/**
* Show an alert with a title, header, content, and automatically close after a few seconds
* If called several times, the previous alert will be closed before showing a new one
* @param title the title of the alert
* @param header the header of the alert
* @param content the content of the alert
* @param seconds the number of seconds before the alert is closed, or put 0 to keep it open
*/
public static void show(String title, String header, String content, int seconds) {
Platform.runLater(()->{
// close previous alert before showing a new one
Optional.ofNullable(currentAlertStage).ifPresent(Stage::close);
Stage alertStage = new Stage();
alertStage.initModality(Modality.APPLICATION_MODAL);
alertStage.initStyle(StageStyle.UTILITY);
alertStage.setAlwaysOnTop(true);
alertStage.setResizable(false);
double screenwidth = Screen.getPrimary().getVisualBounds().getWidth();
double width = screenwidth/4;
double height = width * 9 / 16;
Label headerLabel = new Label(header);
headerLabel.setStyle("-fx-font-weight: bold; -fx-font-size: 16px;");
headerLabel.setMinHeight(height*0.25);
Label contentLabel = new Label(content);
contentLabel.setStyle("-fx-font-size: 12px;");
contentLabel.setMinHeight(height*0.75);
VBox root = new VBox(10, headerLabel, contentLabel);
root.setPrefSize(width, height);
root.setAlignment(Pos.CENTER);
Scene scene = new Scene(root);
alertStage.setScene(scene);
alertStage.setTitle(title);
currentAlertStage = alertStage;
alertStage.show();
shownHeader = header;
shownContent = content;
shownTitle = title;
if (seconds>0){
PauseTransition delay = new PauseTransition(Duration.seconds(seconds));
delay.setOnFinished(e -> {
alertStage.close();
if (currentAlertStage == alertStage) {
currentAlertStage = null;
}
clear();
} );
delay.play();
}
});
}
}

View File

@@ -31,6 +31,7 @@ import org.bytedeco.opencv.global.opencv_imgcodecs;
import org.bytedeco.opencv.global.opencv_imgproc;
import org.bytedeco.opencv.opencv_core.*;
import org.opencv.videoio.Videoio;
import org.tinylog.Logger;
import java.awt.image.BufferedImage;
@@ -48,7 +49,6 @@ import static Config.SomeCodes.*;
import static id.co.gtc.erhacam.Detectors.*;
import static org.bytedeco.opencv.global.opencv_core.CV_8UC3;
import static org.bytedeco.opencv.global.opencv_core.mean;
import static org.bytedeco.opencv.global.opencv_imgcodecs.imwrite;
import static org.bytedeco.opencv.global.opencv_imgproc.*;
@SuppressWarnings({"unused"})
@@ -58,6 +58,7 @@ public class Cameradetail {
isCudaAvailable = opencv_core.getCudaEnabledDeviceCount()>0;
if (isCudaAvailable){
System.out.println("CUDA is available");
opencv_core.printCudaDeviceInfo(0);
} else {
System.out.println("CUDA is not available");
}
@@ -608,23 +609,27 @@ public class Cameradetail {
}
public String GetFullQualityPhotoPath(String directory, String prefix){
if (!ValidDirectory(directory)) directory = currentDirectory;
return Path.of(directory, "FullQuality", makeFileName(prefix,".png")).toString();
//if (!ValidDirectory(directory)) directory = currentDirectory;
//return Path.of(directory, "FullQuality", makeFileName(prefix,".png")).toString();
return Path.of(config.getFullQualityDirectory(), makeFileName(prefix,".png")).toString();
}
public String GetReducedPhotoPath(String directory, String prefix){
if (!ValidDirectory(directory)) directory = currentDirectory;
return Path.of(directory, "Compressed", makeReducedFileName(prefix,".jpg")).toString();
//if (!ValidDirectory(directory)) directory = currentDirectory;
//return Path.of(directory, "Compressed", makeReducedFileName(prefix,".jpg")).toString();
return Path.of(config.getCompressedDirectory(), makeFileName(prefix,".jpg")).toString();
}
public String GetFullQualityCropPhotoPath(String directory, String prefix){
if (!ValidDirectory(directory)) directory = currentDirectory;
return Path.of(directory, "FullQualityCrop", makeFileName(prefix,".png")).toString();
//if (!ValidDirectory(directory)) directory = currentDirectory;
//return Path.of(directory, "FullQualityCrop", makeFileName(prefix,".png")).toString();
return Path.of(config.getFullQualityCropDirectory(), makeFileName(prefix,".png")).toString();
}
public String GetReducedCropPhotoPath(String directory, String prefix){
if (!ValidDirectory(directory)) directory = currentDirectory;
return Path.of(directory, "CompressedCrop", makeReducedFileName(prefix,".jpg")).toString();
//if (!ValidDirectory(directory)) directory = currentDirectory;
//return Path.of(directory, "CompressedCrop", makeReducedFileName(prefix,".jpg")).toString();
return Path.of(config.getCompressedCropDirectory(), makeFileName(prefix,".jpg")).toString();
}
/**
@@ -643,18 +648,10 @@ public class Cameradetail {
}
TakingPhoto.set(true);
if (!BestMat.empty()){
Size sz = BestMat.size();
raise_log("TakePhoto got frame with width: " + sz.width() + " and height: " + sz.height());
// String timestamp = prefix+" "+SomeCodes.GetDateTimeString();
// Scalar color = new Scalar(255, 255, 255, 0); // white
// PutText(BestMat, timestamp, 4.0, color, 2);
// save BestMat at quality 9 PNG
String filename = GetFullQualityCropPhotoPath(directory, prefix);
//String filename = Path.of(directory, "FullQuality", makeFileName(prefix,".png")).toString();
String filename = GetFullQualityPhotoPath(directory, prefix);
if (opencv_imgcodecs.imwrite(filename, BestMat, parampng)){
result.setFullres(filename);
} else System.out.println("TakePhoto failed, Unable to Save FullQUality Photo for camera "+cameratitle.getText());
@@ -664,22 +661,9 @@ public class Cameradetail {
result.setFullcrop(xx);
result.setBestROI(new Rect(BestMatROI.x(), BestMatROI.y(), BestMatROI.width(), BestMatROI.height()));
}
// if (BestMatROI!=null){
// UMat FullCrop = CropUMat(BestMat, BestMatROI);
// if (FullCrop!=null){
// //String roifilename = Path.of(directory, "FullQualityCrop", makeFileName(prefix,".png")).toString();
// String roifilename = GetFullQualityCropPhotoPath(directory, prefix);
// if (!opencv_imgcodecs.imwrite(roifilename, FullCrop, parampng)){
// System.out.println("TakePhoto failed, Unable to Save FullQUalityCrop for camera "+cameratitle.getText());
// } else {
// result.setFullcrop(roifilename);
// result.setBestROI(new Rect(BestMatROI.x(), BestMatROI.y(), BestMatROI.width(), BestMatROI.height()));
// }
// }
// }
// save ReducedMat at 100% JPEG
//String reducedfilename = Path.of(directory, "Compressed", makeReducedFileName(prefix,".jpg")).toString();
String reducedfilename = GetReducedPhotoPath(directory, prefix);
opencv_imgproc.resize(BestMat, ReducedMat, ReducedSize);
if (!opencv_imgcodecs.imwrite(reducedfilename, ReducedMat, paramjpeg)){
@@ -691,19 +675,6 @@ public class Cameradetail {
result.setCompressedcrop(xy);
result.setReducedROI(new Rect(ReducedMatROI.x(), ReducedMatROI.y(), ReducedMatROI.width(), ReducedMatROI.height()));
}
// if (ReducedMatROI!=null){
// UMat ReducedCrop = CropUMat(ReducedMat, ReducedMatROI);
// if (ReducedCrop!=null){
// //String roifilename = Path.of(directory, "CompressedCrop", makeReducedFileName(prefix,".jpg")).toString();
// String roifilename = GetReducedCropPhotoPath(directory, prefix);
// if (!opencv_imgcodecs.imwrite(roifilename, ReducedCrop, paramjpeg)){
// System.out.println("TakePhoto failed, Unable to Save CompressedCrop for camera "+cameratitle.getText());
// } else {
// result.setCompressedcrop(roifilename);
// result.setReducedROI(new Rect(ReducedMatROI.x(), ReducedMatROI.y(), ReducedMatROI.width(), ReducedMatROI.height()));
// }
// }
// }
} else raise_log("TakePhoto failed, Live View is Empty");
} else raise_log("TakePhoto failed, Grabber is null");
@@ -711,22 +682,25 @@ public class Cameradetail {
return result;
}
public String CropBestMat(String directory, String prefix, Rect ROI){
if (!BestMat.empty()) {
UMat cloned = new UMat();
BestMat.copyTo(cloned);
if (!cloned.empty()) {
if (ValidROI(ROI)){
if (ROIInsideUMat(ROI, BestMat)){
UMat cropped = CropUMat(BestMat, ROI);
if (ROIInsideUMat(ROI, cloned)){
UMat cropped = CropUMat(cloned, ROI);
if (cropped != null) {
String filename = GetFullQualityCropPhotoPath(directory, prefix);
if (opencv_imgcodecs.imwrite(filename, cropped, parampng)) {
System.out.println("CropBestMat success, saved as " + filename);
Wait(500);
Logger.info("CropBestMat success, saved as " + filename);
return filename;
} //else System.out.println("CropBestMat failed, Unable to Save BestMat");
} //else System.out.println("CropBestMat failed, Unable to Crop BestMat");
} //else System.out.println("CropBestMat failed, ROI is outside BestMat");
} //else System.out.println("CropBestMat failed, ROI is invalid");
} //else System.out.println("CropBestMat failed, BestMat is empty");
} else Logger.error("CropBestMat failed, Unable to Save BestMat as ",filename);
} else Logger.error("CropBestMat failed, Unable to Crop BestMat");
} else Logger.error("CropBestMat failed, ROI is outside BestMat");
} else Logger.error("CropBestMat failed, ROI is invalid");
} else Logger.error("CropBestMat failed, BestMat is empty");
return null;
}
@@ -738,14 +712,13 @@ public class Cameradetail {
if (cropped!=null){
String filename = GetReducedCropPhotoPath(directory, prefix);
if (opencv_imgcodecs.imwrite(filename, cropped, paramjpeg)){
System.out.println("CropReducedMat success, saved as "+filename);
Wait(100);
Logger.info("CropReducedMat success, saved as ",filename);
return filename;
} //else System.out.println("CropReducedMat failed, Unable to Save ReducedMat");
} //else System.out.println("CropReducedMat failed, Unable to Crop ReducedMat");
} //else System.out.println("CropReducedMat failed, ROI is outside ReducedMat");
} //else System.out.println("CropReducedMat failed, ROI is invalid");
} //else System.out.println("CropReducedMat failed, ReducedMat is empty");
} else Logger.error("CropReducedMat failed, Unable to Save ReducedMat as ",filename);
} else Logger.error("CropReducedMat failed, Unable to Crop ReducedMat");
} else Logger.error("CropReducedMat failed, ROI is outside ReducedMat");
} else Logger.error("CropReducedMat failed, ROI is invalid");
} else Logger.error("CropReducedMat failed, ReducedMat is empty");
return null;
}
@@ -770,7 +743,8 @@ public class Cameradetail {
Capturing.set(false);
if (mGrabber!=null){
try{
mGrabber.stop();
mGrabber.close();
System.out.println("Camera "+cameratitle.getText()+" stopped");
Platform.runLater(()->setCameraStatus("Camera Stopped"));
} catch (Exception e){
raise_log("StopLiveView failed, Unable to Stop Camera, Error: " + e.getMessage());
@@ -827,6 +801,8 @@ public class Cameradetail {
LiveFPS = 0;
mGrabber.start();
mGrabber.flush();
System.out.println("Camera "+cameratitle+" started");
Capturing.set(true);
// just information
@@ -870,6 +846,8 @@ public class Cameradetail {
boolean have_fist = false;
int no_face_counter = 0;
int face_counter = 0;
int open_eye_counter = 0;
int close_eye_counter = 0;
while (Capturing.get()) {
try {
@@ -880,11 +858,26 @@ public class Cameradetail {
if (!Capturing.get()) return null;
IsGrabbingLiveView.set(true);
Frame frame=null;
Frame frame;
try{
frame = mGrabber.grab(); // grab frame
} catch (Exception e){
System.out.println("Exception on grab frame from camera "+cameratitle+", Message : "+e.getMessage());
frame = null;
if (e.getMessage()!=null && e.getMessage().length()>0){
String msg = e.getMessage();
if (msg.contains("start() been called")){
if (Capturing.get()){
System.out.println("Camera "+cameratitle+" has been stopped, restarting");
mGrabber.close();
Wait(100);
mGrabber.start();
mGrabber.flush();
} else {
System.out.println("Camera "+cameratitle+" has been stopped, not restarting");
}
} else System.out.println("Exception on grab frame from camera "+cameratitle+", Message : "+e.getMessage());
}
}
if (frame==null) continue;
Mat mat = matconverter.convert(frame); // convert to Mat
@@ -892,7 +885,10 @@ public class Cameradetail {
UMat originalmat = new UMat();
mat.copyTo(originalmat); // copy to BestMat for using OpenCL
opencv_core.rotate(originalmat, BestMat, opencv_core.ROTATE_90_COUNTERCLOCKWISE);
// revisi 18/03/2025
UMat flippedmat = new UMat();
opencv_core.flip(originalmat, flippedmat, 1); // flip horizontal
opencv_core.rotate(flippedmat, BestMat, opencv_core.ROTATE_90_COUNTERCLOCKWISE);
IsGrabbingLiveView.set(false);
if (!BestMat.empty()) {
@@ -962,21 +958,29 @@ public class Cameradetail {
if (theface.haveEyes()){
// ada mata (buka mata)
close_eye_counter=0;
if (open_eye_counter<1){
open_eye_counter++;
continue;
}
System.out.println("Valid Open Eyes");
if (eye_state==0){
// transisi dari tutup mata ke buka mata
//System.out.println("Eye Open Detected from camera "+cameratitle);
System.out.println("Transition from close to open eyes");
long now = System.currentTimeMillis();
if (waiting_for_second_blink){
long diff = now - last_blink;
// kalau beda waktu antara blink 1 dan blink 2 kurang dari 10 detik
if (diff<=10000){
waiting_for_second_blink = false;
//System.out.println("Double Blink Detected from camera "+cameratitle);
System.out.println("Double Blink Detected from camera "+cameratitle);
if (event!=null) event.onBlink((int)diff);
}
} else {
waiting_for_second_blink = true;
//System.out.println("First Blink Detected from camera "+cameratitle);
System.out.println("First Blink Detected from camera "+cameratitle);
}
last_blink = now;
}
@@ -984,28 +988,36 @@ public class Cameradetail {
} else {
// ada muka, tidak ada mata
// transisi dari buka mata ke tutup mata
open_eye_counter=0;
if (close_eye_counter<1){
close_eye_counter++;
continue;
}
System.out.println("Valid Closed Eyes");
if (eye_state!=0){
//System.out.println("Eye Closed Detected from camera "+cameratitle);
System.out.println("Transition from open to close eyes");
}
eye_state = 0;
}
} else if (have_left_45_face ){
no_face_counter = 0;
if (event!=null) event.onProfileFaceDetector(true, _face_width, _face_height);
} else {
// no face detected, but let's not cancel the previous state immediately
if (no_face_counter>60){
if (no_face_counter>30){
// kalau tidak ada face selama 30 frame, reset state
// 60 frame approximately 2 second
// 30 frame approximately 2 second
eye_state = -1;
last_blink = 0;
waiting_for_second_blink = false;
face_counter = 0;
if (close_eye_counter!=0 || open_eye_counter!=0){
close_eye_counter=0;
open_eye_counter=0;
System.out.println("Reset Open and Close Eyes");
}
if (event!=null) {
event.onFrontalFaceDetector(false, _face_width, _face_height);
event.onProfileFaceDetector(false, _face_width, _face_height);
@@ -1040,7 +1052,9 @@ public class Cameradetail {
updateValue(matToWritableImage(imgmat, imgmat.cols(), imgmat.rows()));
}
} catch (Exception e) {
if (ValidString(e.getMessage())){
raise_log("Unable to Grab Frame, Error: " + e.getMessage());
}
//if (!Capturing.get()) Platform.runLater(this::StopLiveView);
}
}
@@ -1067,17 +1081,19 @@ public class Cameradetail {
return false;
}
/**
* Remap LiveMatROI to BestMatROI and ReducedMatROI Resolution
* @param scaleX scale factor for width
* @param scaleY scale factor for height
*/
public void RemapROI(double scaleX, double scaleY){
public void RemapROI(double scaleX, double scaleY, boolean printdebug){
BestMatROI = null;
ReducedMatROI = null;
if (ValidROI(LiveMatROI)){
if (ROIInsideUMat(LiveMatROI, LiveMat)){
System.out.println("LiveMatROI camera "+cameratitle.getText()+" = "+RectToString(LiveMatROI));
if (printdebug) System.out.println("LiveMatROI camera "+cameratitle.getText()+" = "+RectToString(LiveMatROI));
double scaleXBest = 1.0*BestSize.width()/LiveSize.width();
double scaleYBest = 1.0*BestSize.height()/LiveSize.height();
@@ -1096,8 +1112,11 @@ public class Cameradetail {
HBest = HBest + deltaHBest;
if (HBest>BestSize.height()) HBest = BestSize.height();
BestMatROI = new Rect(XBest, YBest, WBest, HBest);
if (printdebug){
System.out.println("scaleXBest = "+scaleXBest+" scaleYBest = "+scaleYBest);
System.out.println("BestMatROI camera "+cameratitle.getText()+" = "+RectToString(BestMatROI));
}
double scaleXReduced = 1.0*ReducedSize.width()/LiveSize.width();
double scaleYReduced = 1.0*ReducedSize.height()/LiveSize.height();
@@ -1116,8 +1135,11 @@ public class Cameradetail {
HReduced = HReduced + deltaHReduced;
if (HReduced>ReducedSize.height()) HReduced = ReducedSize.height();
ReducedMatROI = new Rect(XReduced, YReduced, WReduced, HReduced);
if (printdebug){
System.out.println("scaleXReduced = "+scaleXReduced+" scaleYReduced = "+scaleYReduced);
System.out.println("ReducedMatROI camera "+cameratitle.getText()+" = "+RectToString(ReducedMatROI));
}
} //else System.out.println("LiveMatROI is Outside LiveMat for camera "+cameratitle.getText());
} //else System.out.println("LiveMatROI is invalid for camera "+cameratitle.getText());

View File

@@ -12,17 +12,14 @@ import ErhaAPI.BarcodeResullt;
import ErhaAPI.PhotoResult;
import ErhaAPI.PatientRecord;
import ErhaAPI.UploadResult;
import FTP.FTPUpload;
import FTP.FTPUploadEvent;
import FTP.FtpMonitorData;
import javafx.application.Platform;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.concurrent.Task;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.layout.AnchorPane;
import javafx.stage.DirectoryChooser;
@@ -64,9 +61,6 @@ public class CaptureView {
private Cameradetail image1, image2, image3, image4, image5;
@FXML
private TextArea directorypath;
@FXML
private TextArea barcodeData;
@FXML
@@ -74,15 +68,6 @@ public class CaptureView {
@FXML
private TextArea PatientName;
@FXML
private Button btnTakePhoto;
@FXML
private Button btnAutoFocus;
@FXML
private AnchorPane progressanchor;
private AudioPlayer audioPlayer;
private String audio_posisikan_muka = "posisikan_wajah.wav";
private String audio_scan_barcode = "scan_barcode.wav";
@@ -91,6 +76,7 @@ public class CaptureView {
private String audio_upload_berhasil = "upload_berhasil.wav";
private String audio_upload_gagal = "upload_gagal.wav";
private String audio_countdown = "countdown321.wav";
private String audio_tahan_posisi = "tahan_posisi.wav";
private List<String> cams;
@@ -105,6 +91,7 @@ public class CaptureView {
private final ErhaAPI erhaAPI = new ErhaAPI(false);
private final double sharpness_threshold = 150;
@FXML
private void ChangeDirectory(){
DirectoryChooser dc = new DirectoryChooser();
@@ -113,7 +100,6 @@ public class CaptureView {
config.SetPhotoDirectory(path);
config.Save();
directorypath.setText(path);
}
private void trigger_autofocus(Cameradetail image) throws InterruptedException {
@@ -139,29 +125,34 @@ public class CaptureView {
}
@SuppressWarnings("resource")
@FXML
private void TakePhotos(){
boolean has_face = Arrays.stream(have_face).anyMatch(AtomicBoolean::get);
if (has_face){
AutoCloseAlert.show("Pengambilan Foto", "Tahan Posisi Anda", "Proses ini kurang lebih 3 detik", 5);
if (audioPlayer!=null && audioPlayer.isInited()){
if (!audioPlayer.getCurrentFile().equals(audio_countdown)) {
audioPlayer.StopCurrentPlayback();
Wait(200);
}
audioPlayer.PlayFile(audio_countdown, ps);
audioPlayer.PlayFile(audio_tahan_posisi, ps);
} else System.out.println("audioPlayer already playing countdown");
}
try{
AutoFocus();
Thread.sleep(2000);
} catch (InterruptedException e){
Logger.error("Error AutoFocus: "+e.getMessage());
}
// try{
// AutoFocus();
// Thread.sleep(1000);
// } catch (InterruptedException e){
// Logger.error("Error AutoFocus: "+e.getMessage());
// }
Size thumbsize = new Size(160,120);
String directory = directorypath.getText();
String directory = config.getPhotoDirectory();
String prefix = RemoveSpaces(medicalRecordID.getText()) ;
if (ValidDirectory(directory)){
if (ValidMedicalRecordId(prefix)){
@@ -175,12 +166,17 @@ public class CaptureView {
Callable<PhotoResult> task1 = ()->{
if (image1!=null) {
image1.RemapROI(0.1,0.3);
image1.RemapROI(0.1,0.3, false);
double sharpness = CalculateSharpness(image1.getBestMat());
if (sharpness<sharpness_threshold){
AutoCloseAlert.show("Take Photos Failed", "Blurred Image Detected", "Blurred Image Detected at Camera 1 with sharpness score "+sharpness, 5);
return null;
}
PhotoResult p1 = image1.TakePhoto(directory,prefix);
//System.out.println("PhotoResult P1 :");
//System.out.println(p1);
if (ValidFile(p1.getFullres())){
if (ValidFile(p1.getCompressedfile())){
p1.setSharpscore(sharpness);
return p1;
}
}
@@ -189,12 +185,16 @@ public class CaptureView {
};
Callable<PhotoResult> task2 = ()->{
if (image2!=null) {
image2.RemapROI(0.1,0.3);
image2.RemapROI(0.1,0.3, false);
double sharpness = CalculateSharpness(image2.getBestMat());
if (sharpness<sharpness_threshold){
AutoCloseAlert.show("Take Photos Failed", "Blurred Image Detected", "Blurred Image Detected at Camera 2 with sharpness score "+sharpness, 5);
return null;
}
PhotoResult p2 = image2.TakePhoto(directory,prefix);
//System.out.println("PhotoResult P2 :");
//System.out.println(p2);
if (ValidFile(p2.getFullres())){
if (ValidFile(p2.getCompressedfile())){
p2.setSharpscore(sharpness);
return p2;
}
}
@@ -204,12 +204,17 @@ public class CaptureView {
Callable<PhotoResult> task3 = ()->{
if (image3!=null) {
image3.RemapROI(0.1,0.3);
image3.RemapROI(0.1,0.3, false);
double sharpness = CalculateSharpness(image3.getBestMat());
if (sharpness<sharpness_threshold){
AutoCloseAlert.show("Take Photos Failed", "Blurred Image Detected", "Blurred Image Detected at Camera 3 with sharpness score "+sharpness, 5);
return null;
}
PhotoResult p3 = image3.TakePhoto(directory,prefix);
//System.out.println("PhotoResult P3 :");
//System.out.println(p3);
if (ValidFile(p3.getFullres())){
if (ValidFile(p3.getCompressedfile())){
p3.setSharpscore(sharpness);
return p3;
}
}
@@ -220,12 +225,17 @@ public class CaptureView {
Callable<PhotoResult> task4 = ()->{
if (image4!=null) {
image4.RemapROI(0.1,0.3);
image4.RemapROI(0.1,0.3, false);
double sharpness = CalculateSharpness(image4.getBestMat());
if (sharpness<sharpness_threshold){
AutoCloseAlert.show("Take Photos Failed", "Blurred Image Detected", "Blurred Image Detected at Camera 4 with sharpness score "+sharpness, 5);
return null;
}
PhotoResult p4 = image4.TakePhoto(directory,prefix);
//System.out.println("PhotoResult P4 :");
//System.out.println(p4);
if (ValidFile(p4.getFullres())){
if (ValidFile(p4.getCompressedfile())){
p4.setSharpscore(sharpness);
return p4;
}
}
@@ -236,12 +246,17 @@ public class CaptureView {
Callable<PhotoResult> task5 = ()->{
if (image5!=null) {
image5.RemapROI(0.1,0.3);
image5.RemapROI(0.1,0.3, false);
double sharpness = CalculateSharpness(image5.getBestMat());
if (sharpness<sharpness_threshold){
AutoCloseAlert.show("Take Photos Failed", "Blurred Image Detected", "Blurred Image Detected at Camera 5 with sharpness score "+sharpness, 5);
return null;
}
PhotoResult p5 = image5.TakePhoto(directory,prefix);
//System.out.println("PhotoResult P5 :");
//System.out.println(p5);
if (ValidFile(p5.getFullres())){
if (ValidFile(p5.getCompressedfile())){
p5.setSharpscore(sharpness);
return p5;
}
}
@@ -279,6 +294,37 @@ public class CaptureView {
String timestamp = SomeCodes.GetDateTimeString();
System.out.println("Creating timestamp: "+timestamp);
// check for blurred image
double score1=0, score2=0, score3=0, score4=0, score5=0;
if (p1!=null){
score1 = p1.getSharpscore();
}
if (p2!=null){
score2 = p2.getSharpscore();
}
if (p3!=null){
score3 = p3.getSharpscore();
}
if (p4!=null){
score4 = p4.getSharpscore();
}
if (p5!=null){
score5 = p5.getSharpscore();
}
System.out.println("Sharpness score: "+score1+", "+score2+", "+score3+", "+score4+", "+score5);
double lowest = FindLowestValue(score1,score2,score3,score4,score5);
if (lowest<sharpness_threshold){
String culprit = "";
if (lowest==score1) culprit = "camera 1";
else if (lowest==score2) culprit = "camera 2";
else if (lowest==score3) culprit = "camera 3";
else if (lowest==score4) culprit = "camera 4";
else if (lowest==score5) culprit = "camera 5";
AutoCloseAlert.show("Take Photos Failed", "Blurred Image Detected", "Blurred Image Detected at "+culprit+" with sharpness score "+lowest, 5);
return;
}
Rect bestroi = null;
Rect reducedroi = null;
if (p1!=null && p1.getBestROI()!=null){
@@ -327,18 +373,9 @@ public class CaptureView {
reducedroi = p5.getReducedROI();
}
prc.setFileLeft90(p1.getFullres());
prc.setFileLeft45(p2.getFullres());
prc.setFileCenter(p3.getFullres());
prc.setFileRight45(p4.getFullres());
prc.setFileRight90(p5.getFullres());
prc.setCompressedLeft90(p1.getCompressedfile());
prc.setCompressedLeft45(p2.getCompressedfile());
prc.setCompressedCenter(p3.getCompressedfile());
prc.setCompressedRight45(p4.getCompressedfile());
prc.setCompressedRight90(p5.getCompressedfile());
if (p1!=null){
prc.setFileLeft90(ValidFile(p1.getFullres()) ? p1.getFullres() : "");
prc.setCompressedLeft90(ValidFile(p1.getCompressedfile()) ? p1.getCompressedfile() : "");
if (ValidFile(p1.getFullcrop())){
// ada crop
prc.setCroppedLeft90(p1.getFullcrop());
@@ -346,6 +383,18 @@ public class CaptureView {
String xx = image1.CropBestMat(directory,prefix, bestroi);
if (ValidFile(xx)) prc.setCroppedLeft90(xx);
}
if (ValidFile(p1.getCompressedcrop())){
prc.setCompressedCropLeft90(p1.getCompressedcrop());
} else {
String xx =image1.CropReducedMat(directory,prefix, reducedroi);
if (ValidFile(xx)) prc.setCompressedCropLeft90(xx);
}
String thumb1 = MakeThumbfile(p1.getFullres(), thumbsize);
if (ValidFile(thumb1)) prc.setThumbLeft90(thumb1);
}
if (p2!=null){
prc.setFileLeft45(ValidFile(p2.getFullres()) ? p2.getFullres() : "");
prc.setCompressedLeft45(ValidFile(p2.getCompressedfile()) ? p2.getCompressedfile() : "");
if (ValidFile(p2.getFullcrop())){
// ada crop
prc.setCroppedLeft45(p2.getFullcrop());
@@ -353,6 +402,18 @@ public class CaptureView {
String xx = image2.CropBestMat(directory,prefix, bestroi);
if (ValidFile(xx)) prc.setCroppedLeft45(xx);
}
if (ValidFile(p2.getCompressedcrop())){
prc.setCompressedCropLeft45(p2.getCompressedcrop());
} else {
String xx = image2.CropReducedMat(directory,prefix, reducedroi);
if (ValidFile(xx)) prc.setCompressedCropLeft45(xx);
}
String thumb2 = MakeThumbfile(p2.getFullres(), thumbsize);
if (ValidFile(thumb2)) prc.setThumbLeft45(thumb2);
}
if (p3!=null){
prc.setFileCenter(ValidFile(p3.getFullres()) ? p3.getFullres() : "");
prc.setCompressedCenter(ValidFile(p3.getCompressedfile()) ? p3.getCompressedfile() : "");
if (ValidFile(p3.getFullcrop())){
// ada crop
prc.setCroppedCenter(p3.getFullcrop());
@@ -360,6 +421,18 @@ public class CaptureView {
String xx = image3.CropBestMat(directory,prefix, bestroi);
if (ValidFile(xx)) prc.setCroppedCenter(xx);
}
if (ValidFile(p3.getCompressedcrop())){
prc.setCompressedCropCenter(p3.getCompressedcrop());
} else {
String xx = image3.CropReducedMat(directory,prefix, reducedroi);
if (ValidFile(xx)) prc.setCompressedCropCenter(xx);
}
String thumb3 = MakeThumbfile(p3.getFullres(), thumbsize);
if (ValidFile(thumb3)) prc.setThumbCenter(thumb3);
}
if (p4!=null){
prc.setFileRight45(ValidFile(p4.getFullres()) ? p4.getFullres() : "");
prc.setCompressedRight45(ValidFile(p4.getCompressedfile()) ? p4.getCompressedfile() : "");
if (ValidFile(p4.getFullcrop())){
// ada crop
prc.setCroppedRight45(p4.getFullcrop());
@@ -367,6 +440,18 @@ public class CaptureView {
String xx = image4.CropBestMat(directory,prefix, bestroi);
if (ValidFile(xx)) prc.setCroppedRight45(xx);
}
if (ValidFile(p4.getCompressedcrop())){
prc.setCompressedCropRight45(p4.getCompressedcrop());
} else {
String xx = image4.CropReducedMat(directory,prefix, reducedroi);
if (ValidFile(xx)) prc.setCompressedCropRight45(xx);
}
String thumb4 = MakeThumbfile(p4.getFullres(), thumbsize);
if (ValidFile(thumb4)) prc.setThumbRight45(thumb4);
}
if (p5!=null){
prc.setFileRight90(ValidFile(p5.getFullres()) ? p5.getFullres() : "");
prc.setCompressedRight90(ValidFile(p5.getCompressedfile()) ? p5.getCompressedfile() : "");
if (ValidFile(p5.getFullcrop())){
// ada crop
prc.setCroppedRight90(p5.getFullcrop());
@@ -374,73 +459,32 @@ public class CaptureView {
String xx = image5.CropBestMat(directory,prefix, bestroi);
if (ValidFile(xx)) prc.setCroppedRight90(xx);
}
if (ValidFile(p1.getCompressedcrop())){
prc.setCompressedCropLeft90(p1.getCompressedcrop());
} else {
String xx =image1.CropReducedMat(directory,prefix, reducedroi);
if (ValidFile(xx)) prc.setCompressedCropLeft90(xx);
}
if (ValidFile(p2.getCompressedcrop())){
prc.setCompressedCropLeft45(p2.getCompressedcrop());
} else {
String xx = image2.CropReducedMat(directory,prefix, reducedroi);
if (ValidFile(xx)) prc.setCompressedCropLeft45(xx);
}
if (ValidFile(p3.getCompressedcrop())){
prc.setCompressedCropCenter(p3.getCompressedcrop());
} else {
String xx = image3.CropReducedMat(directory,prefix, reducedroi);
if (ValidFile(xx)) prc.setCompressedCropCenter(xx);
}
if (ValidFile(p4.getCompressedcrop())){
prc.setCompressedCropRight45(p4.getCompressedcrop());
} else {
String xx = image4.CropReducedMat(directory,prefix, reducedroi);
if (ValidFile(xx)) prc.setCompressedCropRight45(xx);
}
if (ValidFile(p5.getCompressedcrop())){
prc.setCompressedCropRight90(p5.getCompressedcrop());
} else {
String xx= image5.CropReducedMat(directory,prefix, reducedroi);
if (ValidFile(xx)) prc.setCompressedCropRight90(xx);
}
String thumb1 = MakeThumbfile(p1.getFullres(), thumbsize);
if (ValidFile(thumb1)) prc.setThumbLeft90(thumb1);
String thumb2 = MakeThumbfile(p2.getFullres(), thumbsize);
if (ValidFile(thumb2)) prc.setThumbLeft45(thumb2);
String thumb3 = MakeThumbfile(p3.getFullres(), thumbsize);
if (ValidFile(thumb3)) prc.setThumbCenter(thumb3);
String thumb4 = MakeThumbfile(p4.getFullres(), thumbsize);
if (ValidFile(thumb4)) prc.setThumbRight45(thumb4);
String thumb5 = MakeThumbfile(p5.getFullres(), thumbsize);
if (ValidFile(thumb5)) prc.setThumbRight90(thumb5);
}
long duration = (System.nanoTime() - nanostart) / 1000000; // in milliseconds
System.out.println("TakePhotos duration: "+duration+" ms");
Platform.runLater(()->{
progressanchor.getChildren().clear();
barcodeData.setText("");
medicalRecordID.setText("");
PatientName.setText("");
isTakingPhoto.set(false);
});
AutoCloseAlert.show("Photos Taken", "Photos Taken", "Photos Taken", 5);
if (audioPlayer!=null && audioPlayer.isInited()){
if (!audioPlayer.getCurrentFile().equals(audio_pengambilan_berhasil)) {
audioPlayer.StopCurrentPlayback();
Wait(200);
}
audioPlayer.PlayFile(audio_pengambilan_berhasil, ps);
} else System.out.println("audioPlayer already playing pengambilan berhasil");
}
// file untuk di upload
String[] files = prc.compressed();
if (files.length>0){
InsertSQL(prc);
@@ -450,7 +494,7 @@ public class CaptureView {
int totalfiles = files.length;
int counter = 0;
for (String ff : files) {
UploadResult ur = erhaAPI.Upload_File(prefix, ff);
UploadResult ur = erhaAPI.Upload_File(prefix, ff,true);
if (ur != null) {
if (ur.message.startsWith("Record has been created")) {
counter++;
@@ -475,90 +519,57 @@ public class CaptureView {
uploadtask.setOnSucceeded(e-> {
System.out.println("UploadTask succeeded");
if (audioPlayer!=null && audioPlayer.isInited()){
if (!audioPlayer.getCurrentFile().equals(audio_upload_berhasil)) {
audioPlayer.StopCurrentPlayback();
Wait(200);
}
audioPlayer.PlayFile(audio_upload_berhasil, ps);
audioPlayer.WaitUntilFinished();
} else System.out.println("audioPlayer already playing upload berhasil");
}
AutoCloseAlert.show("Upload Success", "Upload Success", "Upload Success", 5);
Platform.runLater(()->{
barcodeData.setText("");
medicalRecordID.setText("");
PatientName.setText("");
isTakingPhoto.set(false);
});
});
uploadtask.setOnFailed(e-> {
System.out.println("UploadTask failed");
if (audioPlayer!=null && audioPlayer.isInited()){
if (!audioPlayer.getCurrentFile().equals(audio_upload_gagal)) {
audioPlayer.StopCurrentPlayback();
Wait(200);
}
audioPlayer.PlayFile(audio_upload_gagal, ps);
audioPlayer.WaitUntilFinished();
} else System.out.println("audioPlayer already playing upload gagal");
}
AutoCloseAlert.show("Upload Failed", "Upload Failed", "Upload Failed", 5);
Platform.runLater(()->{
barcodeData.setText("");
medicalRecordID.setText("");
PatientName.setText("");
isTakingPhoto.set(false);
});
});
new Thread(uploadtask).start();
} else ShowAlert(AlertType.ERROR, "Error", "No Photos Taken", "No Photos Taken, please check camera");
} else ShowAlert(AlertType.ERROR, "Error", "Invalid Prefix", "Please input valid prefix or scan QR Code");
} else ShowAlert(AlertType.ERROR,"Error","Invalid Directory","Please select valid directory");
// new Thread(()-> {
// try{
// InetAddress target = InetAddress.getByName(config.getFTPHost());
// int port = toInt(config.getFTPPort());
// if (target.isReachable(2000)){
// Socket socket = new Socket();
// InetSocketAddress isa = new InetSocketAddress(target, port);
// socket.connect(isa,2000);
// socket.close();
// // sampai sini berarti FTP Host reachable
// UploadToFTP(files);
// } else throw new Exception("FTP Host not reachable");
// } catch (Exception e){
// Logger.error("Error UploadToFTP: "+e.getMessage());
// Platform.runLater(()->{
// Alert alert = new Alert(AlertType.ERROR);
// alert.setTitle("Error");
// alert.setHeaderText("Upload to FTP Failed");
// alert.setContentText("Error: "+e.getMessage());
// alert.showAndWait();
// });
//
// }
// }).start();
} else {
Alert Alert = new Alert(AlertType.ERROR);
Alert.setTitle("Error");
Alert.setHeaderText("No Photos Taken");
Alert.setContentText("No Photos Taken, please check camera");
Alert.showAndWait();
}
} else {
Alert Alert = new Alert(AlertType.ERROR);
Alert.setTitle("Error");
Alert.setHeaderText("Invalid Prefix");
Alert.setContentText("Please input valid prefix or scan QR Code");
Alert.showAndWait();
}
} else {
Alert Alert = new Alert(AlertType.ERROR);
Alert.setTitle("Error");
Alert.setHeaderText("Invalid Directory");
Alert.setContentText("Please select valid directory");
Alert.showAndWait();
}
} else {
AutoCloseAlert.show("Error", "No Face Detected", "No Face Detected", 5);
if (audioPlayer!=null && audioPlayer.isInited()){
if (!audioPlayer.getCurrentFile().equals(audio_posisikan_muka)) {
audioPlayer.StopCurrentPlayback();
Wait(200);
}
audioPlayer.PlayFile(audio_posisikan_muka, ps);
} else System.out.println("audioPlayer already playing posisikan muka");
}
}
@@ -566,11 +577,6 @@ public class CaptureView {
}
private void UpdateBtnTakePhoto(){
boolean valid = ValidDirectory(directorypath.getText()) && ValidString(barcodeData.getText()) && ValidString(medicalRecordID.getText()) && ValidString(PatientName.getText());
btnTakePhoto.setDisable(!valid);
}
@FXML
public void initialize(){
audio_posisikan_muka = ExtractResource("/posisikan_wajah.wav");
@@ -580,16 +586,29 @@ public class CaptureView {
audio_upload_berhasil = ExtractResource("/upload_berhasil.wav");
audio_upload_gagal = ExtractResource("/upload_gagal.wav");
audio_countdown = ExtractResource("/countdown321.wav");
audio_tahan_posisi = ExtractResource("/tahan_posisi.wav");
//tambahan 19/03/2025
barcodeData.textProperty().addListener(new InvalidationListener() {
@Override
public void invalidated(Observable observable) {
String barcode = barcodeData.getText();
System.out.println("barcodeData invalidated, value: "+barcode);
if (ValidBarCode(barcode)){
if (AutoCloseAlert.shownTitle.equals("Scan Barcode")){
AutoCloseAlert.close();
}
} else {
AutoCloseAlert.show("Scan Barcode", "Silahkan Scan Barcode Anda", "Arahkan kertas barcode ke kamera", 0);
}
}
});
barcodeData.setText("");
audioPlayer = new AudioPlayer(1,48000);
Logger.info("Audio Player : "+(audioPlayer.isInited()? "Inited" : "Not Inited"));
btnTakePhoto.setDisable(true);
directorypath.textProperty().addListener((obs, oldval, newval)-> UpdateBtnTakePhoto());
barcodeData.textProperty().addListener((obs, oldval, newval)-> UpdateBtnTakePhoto());
medicalRecordID.textProperty().addListener((obs, oldval, newval)-> UpdateBtnTakePhoto());
PatientName.textProperty().addListener((obs, oldval, newval)-> UpdateBtnTakePhoto());
cams = null;
try{
String[] xxx = VideoInputFrameGrabber.getDeviceDescriptions();
@@ -678,10 +697,9 @@ public class CaptureView {
}
}
directorypath.setText(config.getPhotoDirectory());
progressanchor.prefWidthProperty().bind(controlpane.widthProperty());
});
}
public void Unload(){
@@ -879,7 +897,7 @@ public class CaptureView {
Task<PatientRecord> checkpatientID = new Task<>() {
@Override
protected PatientRecord call() {
BarcodeResullt br = erhaAPI.Validate_Barcode(finalbarCode);
BarcodeResullt br = erhaAPI.Validate_Barcode(finalbarCode,true);
if (br!=null){
if (br.message.startsWith("Records found")){
if (br.data!=null && br.data.length>0){
@@ -911,8 +929,8 @@ public class CaptureView {
if (!audioPlayer.getCurrentFile().equals(audio_posisikan_muka)) {
audioPlayer.StopCurrentPlayback();
Wait(200);
}
audioPlayer.PlayFile(audio_posisikan_muka, ps);
} else System.out.println("audioPlayer already playing posisikan muka");
}
}
@@ -927,6 +945,7 @@ public class CaptureView {
});
System.out.println("checkpatientID failed");
AutoCloseAlert.show("Error","checkpatientID failed","checkpatientID failed",5);
});
new Thread(checkpatientID).start();
@@ -1001,15 +1020,18 @@ public class CaptureView {
String prefix = medicalRecordID.getText();
if (!prefix.isEmpty()){
System.out.println("Prefix valid, taking photo");
btnTakePhoto.fire();
TakePhotos();
} else {
System.out.println("Prefix invalid, not taking photo");
isTakingPhoto.set(false);
AutoCloseAlert.show("QR Code Not Available", "", "Please scan QR before continue", 5);
if (audioPlayer!=null && audioPlayer.isInited()){
if (!audioPlayer.getCurrentFile().equals(audio_scan_barcode)) {
audioPlayer.StopCurrentPlayback();
Wait(200);
}
audioPlayer.PlayFile(audio_scan_barcode, ps);
} else System.out.println("audioPlayer already playing scan barcode");
}
}
@@ -1117,157 +1139,6 @@ public class CaptureView {
}
}
@Deprecated
private void UploadToFTP(String[] files){
final double uploadprogressheight = 50;
Map<String, UploadProgress> progressmap = new HashMap<>();
// Load uploadprogress.fxml for each file
for (String filetoupload : files){
Task<AnchorPane> loadtask = new Task<>() {
@Override
protected AnchorPane call() throws Exception {
FXMLLoader loader = new FXMLLoader(getClass().getResource("uploadprogress.fxml"));
AnchorPane pane = loader.load();
pane.prefWidthProperty().bind(progressanchor.widthProperty());
pane.setPrefHeight(uploadprogressheight);
UploadProgress up = loader.getController();
up.SetFile(filetoupload);
up.SetStatus("Initialized");
up.SetProgress(0,0);
int ii = progressmap.size();
AnchorPane.setTopAnchor(pane, (ii*uploadprogressheight)+10);
progressmap.put(GetFileName(filetoupload), up);
return pane;
}
};
// kalau berhasil, add ke progressanchor
loadtask.setOnSucceeded(e-> progressanchor.getChildren().add(loadtask.getValue()));
// kalau gagal, log error
loadtask.setOnFailed(e-> Logger.error("Error LoadTask: {}",e.getSource().getMessage()));
new Thread(loadtask).start();
}
InvalidationListener progressanchorlistener = observable -> {
// kalau sudah selesai load semua, mulai upload
Logger.info("Progress Anchor Children Size: {}", progressanchor.getChildren().size());
if (progressanchor.getChildren().size()==files.length){
Task<FtpMonitorData> monitorFTP = new Task<>() {
@Override
protected FtpMonitorData call() throws Exception {
FTPUpload ftp = new FTPUpload(config.getFTPHost(), toInt(config.getFTPPort()), config.getFTPUser(), config.getFTPPass(), config.getFTPPath());
ftp.UploadFile(new FTPUploadEvent() {
@Override
public void onUploadSuccess(String file) {
Logger.info("Upload Success: {}" ,file);
String filename = GetFileName(file);
UploadProgress up = progressmap.get(filename);
if (up!=null){
updateValue(new FtpMonitorData("Success", filename, up, 1, 1));
// Platform.runLater(()->{
// up.SetStatus("Success");
// up.SetProgress(1,1);
// });
}
}
@Override
public void onUploadFailed(String file) {
Logger.info("Upload Failed: {}",file);
String filename = GetFileName(file);
UploadProgress up = progressmap.get(filename);
if (up!=null){
updateValue(new FtpMonitorData("Failed", filename, up, 1, 0));
// Platform.runLater(()->{
// up.SetStatus("Failed");
// up.SetProgress(0,1);
// });
}
}
@Override
public void onUploadProgress(String file, long bytes, long total) {
String filename = GetFileName(file);
UploadProgress up = progressmap.get(filename);
if (up!=null){
updateValue(new FtpMonitorData("Uploading", filename, up, total, bytes));
// Platform.runLater(()->up.SetProgress(bytes, total));
}
}
@Override
public void onUploadStarted(String file) {
Logger.info("Upload Started: {}",file);
String filename = GetFileName(file);
UploadProgress up = progressmap.get(filename);
if (up!=null){
updateValue(new FtpMonitorData("Started", filename, up, 0, 0));
// Platform.runLater(()->{
// up.SetStatus("Started");
// up.SetProgress(0,0);
// });
}
}
@Override
public void uploadLog(String msg) {
Logger.info("Upload Log: {}",msg);
}
@Override
public void onUploadFinished(int total, int success, int failed, String[] files) {
Logger.info("Upload Finished, Total: {}, Success: {}, Failed: {}", total, success, failed);
Platform.runLater(()->{
if (!audioPlayer.getCurrentFile().equals(audio_upload_berhasil)) {
audioPlayer.StopCurrentPlayback();
Wait(200);
}
audioPlayer.PlayFile(audio_upload_berhasil, ps);
Alert Alert = new Alert(AlertType.INFORMATION);
Alert.setTitle("Upload Finished");
Alert.setHeaderText("Upload Finished");
Alert.setContentText("Total: "+total+"\nSuccess: "+success+"\nFailed: "+failed);
Alert.showAndWait();
});
}
}, files);
// Task selesai, return null
return null;
}
};
monitorFTP.valueProperty().addListener(
(observable1, oldValue, newValue) -> {
if (newValue!=null){
if (newValue.progress!=null){
newValue.progress.SetStatus(newValue.information);
newValue.progress.SetProgress(newValue.current, newValue.total);
}
}
}
);
new Thread(monitorFTP).start();
}
};
progressanchor.getChildren().addListener(progressanchorlistener);
}
private void InsertSQL(PhotoReviewClass prc){
Sqlite sql = new Sqlite();
sql.Insert(prc);

View File

@@ -14,10 +14,9 @@ import static Config.SomeCodes.IsInsideRect;
public class Detectors {
public static CascadeClassifier frontalfaceDetector;
private static CascadeClassifier eyeDetector;
private static CascadeClassifier profilefaceDetector;
private static CascadeClassifier palmDetector;
private static CascadeClassifier fistDetector;
//private static CascadeClassifier palmDetector;
//private static CascadeClassifier fistDetector;
private static double scaleFactor = 1.1;
private final static int minNeighbors = 3;
@@ -37,43 +36,43 @@ public class Detectors {
LoadProfileFaceDetector();
LoadFistDetector();
LoadRightPalmDetector();
//LoadFistDetector();
//LoadRightPalmDetector();
}
private static void LoadFistDetector(){
String filename = SomeCodes.ExtractResource("/fist.xml");
if (filename!=null) {
Logger.info("Fist Detector file : " + filename);
if (fistDetector ==null) {
try{
// private static void LoadFistDetector(){
// String filename = SomeCodes.ExtractResource("/fist.xml");
// if (filename!=null) {
// Logger.info("Fist Detector file : " + filename);
// if (fistDetector ==null) {
// try{
//
// fistDetector = new CascadeClassifier(filename);
// Logger.info("FistDetector loaded");
// } catch (Exception e){
// Logger.error("Exception on loading FistDetector : " + e.getMessage());
// }
//
// } else Logger.info("FistDetector already loaded");
// } else Logger.error("Unable to extract fist detector file");
// }
fistDetector = new CascadeClassifier(filename);
Logger.info("FistDetector loaded");
} catch (Exception e){
Logger.error("Exception on loading FistDetector : " + e.getMessage());
}
} else Logger.info("FistDetector already loaded");
} else Logger.error("Unable to extract fist detector file");
}
private static void LoadRightPalmDetector(){
String filename = SomeCodes.ExtractResource("/rpalm.xml");
if (filename!=null) {
Logger.info("Right Palm Detector file : " + filename);
if (palmDetector ==null) {
try{
palmDetector = new CascadeClassifier(filename);
Logger.info("RightPalmDetector loaded");
} catch (Exception e){
Logger.error("Exception on loading RightPalmDetector : " + e.getMessage());
}
} else Logger.info("RightPalmDetector already loaded");
} else Logger.error("Unable to extract right palm detector file");
}
// private static void LoadRightPalmDetector(){
// String filename = SomeCodes.ExtractResource("/rpalm.xml");
// if (filename!=null) {
// Logger.info("Right Palm Detector file : " + filename);
// if (palmDetector ==null) {
// try{
//
// palmDetector = new CascadeClassifier(filename);
// Logger.info("RightPalmDetector loaded");
// } catch (Exception e){
// Logger.error("Exception on loading RightPalmDetector : " + e.getMessage());
// }
//
// } else Logger.info("RightPalmDetector already loaded");
// } else Logger.error("Unable to extract right palm detector file");
// }
private static void LoadFrontalFaceDetector(){
String filename = SomeCodes.ExtractResource("/haarcascade_frontalface_alt.xml");
@@ -129,15 +128,15 @@ public class Detectors {
public static boolean HavePalm(UMat graymat){
RectVector palms = Detect(graymat, palmDetector);
return palms!=null && palms.size()>0;
}
public static boolean HaveFist(UMat graymat){
RectVector fists = Detect(graymat, fistDetector);
return fists!=null && fists.size()>0;
}
// public static boolean HavePalm(UMat graymat){
// RectVector palms = Detect(graymat, palmDetector);
// return palms!=null && palms.size()>0;
// }
//
// public static boolean HaveFist(UMat graymat){
// RectVector fists = Detect(graymat, fistDetector);
// return fists!=null && fists.size()>0;
// }
/**

View File

@@ -30,12 +30,11 @@ public class MainApplication extends Application {
if (UserID.equals("14022025")){
Logger.info("Secure Dongle UserID valid");
FXMLLoader fxmlLoader = new FXMLLoader(MainApplication.class.getResource("main-view.fxml"));
Screen screen = Screen.getPrimary();
Rectangle2D screenbound = screen.getVisualBounds();
Scene scene = new Scene(fxmlLoader.load(), screenbound.getWidth(), screenbound.getHeight());
stage.setTitle("MultiCam Capture App for ERHA 18022025-032");
stage.setTitle("MultiCam Capture App for ERHA 11032025-006");
stage.setScene(scene);
stage.setResizable(true);
stage.setMaximized(true);

View File

@@ -15,6 +15,7 @@ import org.tinylog.Logger;
import java.io.File;
import java.nio.file.Path;
import static Config.SomeCodes.ShowAlert;
import static Config.SomeCodes.config;
public class PhotoRow {
@@ -47,18 +48,22 @@ public class PhotoRow {
imgview.setStyle(borderstyle);
imgview.setOnMouseClicked(e->{
if (e.getClickCount()>=2){
//System.out.println("Photo path: "+photopath);
File ff = new File(photopath);
String hires = Path.of(config.getPhotoDirectory(), ff.getName()).toString();
// System.out.println("Config exists : "+(config!=null));
// System.out.println("Photo directory: "+config.getPhotoDirectory());
// System.out.println("Full quality directory: "+config.getFullQualityDirectory());
// System.out.println("Full Quality Crop directory: "+config.getFullQualityCropDirectory());
// System.out.println("Reduced quality directory: "+config.getCompressedDirectory());
// System.out.println("Reduced quality crop directory: "+config.getCompressedCropDirectory());
//String hires = Path.of(config.getPhotoDirectory(), ff.getName()).toString();
String hires = Path.of(config.getFullQualityDirectory(), ff.getName()).toString();
//System.out.println("Hires: "+hires);
File hiresfile = new File(hires);
if (hiresfile.isFile()){
System.out.println("Opening file: "+hires);
SomeCodes.OpenPictureInDefaultViewer(hires);
} else {
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle("Error");
alert.setHeaderText("File not found");
alert.setContentText("File not found: "+hires);
alert.showAndWait();
}
} else ShowAlert(Alert.AlertType.ERROR, "Error", "File not found", "File not found: "+hires);
e.consume();
}
});

View File

@@ -6,6 +6,7 @@ import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TextField;
import javafx.stage.DirectoryChooser;
import javafx.stage.FileChooser;
import lombok.val;
import org.bytedeco.javacv.VideoInputFrameGrabber;
@@ -13,21 +14,9 @@ import org.tinylog.Logger;
import java.io.File;
import static Config.SomeCodes.ValidString;
import static Config.SomeCodes.config;
import static Config.SomeCodes.*;
public class SettingView {
@FXML
private TextField AudioPhase1;
@FXML
private TextField AudioPhase2;
@FXML
private TextField AudioPhase3;
@FXML
private TextField AudioPhase4;
@FXML
private TextField AudioPhase5;
@FXML
private ComboBox<String> CameraLeft90;
@FXML
@@ -50,6 +39,11 @@ public class SettingView {
@FXML
private TextField FTPPath;
@FXML
private TextField PhotoDirectoryPath;
final FileChooser jfc = new FileChooser();
String[] cameranames = null;
@@ -63,6 +57,17 @@ public class SettingView {
@FXML
private TextField cascadeMaxSize;
@FXML
private void ChangePhotoDirectoryPath(){
DirectoryChooser dc = new DirectoryChooser();
dc.setTitle("Select Directory");
String path = dc.showDialog(null).getAbsolutePath();
config.SetPhotoDirectory(path);
config.Save();
PhotoDirectoryPath.setText(path);
}
@FXML
private void CascadeSettingApply(){
String minsize = cascadeMinSize.getText();
@@ -87,11 +92,8 @@ public class SettingView {
Detectors.setFaceMaxSize(max);
Detectors.setFaceMinSize(min);
Detectors.setScaleFactor(scale);
val alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("Cascade Setting");
alert.setHeaderText("Cascade Setting Saved");
alert.setContentText("Cascade Setting Saved Successfully");
alert.showAndWait();
ShowAlert(Alert.AlertType.INFORMATION, "Cascade Setting", "Cascade Setting Saved", "Cascade Setting Saved Successfully");
} else show_cascade_alert("Max Size must be greater than Min Size");
} else show_cascade_alert("Min Size must be greater than 0");
} else show_cascade_alert("Scale Factor must be greater than 1.0");
@@ -105,11 +107,7 @@ public class SettingView {
}
private void show_cascade_alert(String content){
val alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle("Cascade Setting Error");
alert.setHeaderText("Cascade Setting Error");
alert.setContentText(content);
alert.showAndWait();
ShowAlert(Alert.AlertType.ERROR, "Cascade Setting Error", "Cascade Setting Error", content);
}
@FXML
@@ -129,11 +127,6 @@ public class SettingView {
Platform.runLater(()->{
AudioPhase1.setText(config.getAudioPhase1());
AudioPhase2.setText(config.getAudioPhase2());
AudioPhase3.setText(config.getAudioPhase3());
AudioPhase4.setText(config.getAudioPhase4());
AudioPhase5.setText(config.getAudioPhase5());
CameraLeft90.getItems().clear();
CameraLeft45.getItems().clear();
@@ -168,6 +161,8 @@ public class SettingView {
FTPPass.setText(config.getFTPPass());
FTPPath.setText(config.getFTPPath());
PhotoDirectoryPath.setText(config.getPhotoDirectory());
cascadeScaleFactor.setText(String.valueOf(config.getCascadeScaleFactor()));
cascadeMinSize.setText(String.valueOf(config.getCascadeMinSize()));
cascadeMaxSize.setText(String.valueOf(config.getCascadeMaxSize()));
@@ -178,52 +173,6 @@ public class SettingView {
config.Save();
}
@FXML
private void BrowseAudioPhase1(){
File file = jfc.showOpenDialog(null);
if (file!=null){
config.SetAudioPhase1(file.getAbsolutePath());
AudioPhase1.setText(config.getAudioPhase1());
}
}
@FXML
private void BrowseAudioPhase2(){
File file = jfc.showOpenDialog(null);
if (file!=null){
config.SetAudioPhase2(file.getAbsolutePath());
AudioPhase2.setText(config.getAudioPhase2());
}
}
@FXML
private void BrowseAudioPhase3(){
File file = jfc.showOpenDialog(null);
if (file!=null){
config.SetAudioPhase3(file.getAbsolutePath());
AudioPhase3.setText(config.getAudioPhase3());
}
}
@FXML
private void BrowseAudioPhase4(){
File file = jfc.showOpenDialog(null);
if (file!=null){
config.SetAudioPhase4(file.getAbsolutePath());
AudioPhase4.setText(config.getAudioPhase4());
}
}
@FXML
private void BrowseAudioPhase5(){
File file = jfc.showOpenDialog(null);
if (file!=null){
config.SetAudioPhase5(file.getAbsolutePath());
AudioPhase5.setText(config.getAudioPhase5());
}
}
@FXML
private void ApplyCameraLeft90(){
config.SetCameraLeft90(CameraLeft90.getValue());
@@ -261,18 +210,8 @@ public class SettingView {
config.SetFTPPass(FTPPass.getText());
config.SetFTPPath(FTPPath.getText());
val alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("FTP Configuration");
alert.setHeaderText("FTP Configuration Saved");
alert.setContentText("FTP Configuration Saved Successfully");
alert.showAndWait();
} else {
val alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle("FTP Error");
alert.setHeaderText("FTP Configuration Error");
alert.setContentText("FTP Configuration is incorrect, please check your FTP Configuration");
alert.showAndWait();
}
ShowAlert(Alert.AlertType.INFORMATION, "FTP Configuration", "FTP Configuration Saved", "FTP Configuration Saved Successfully");
} else ShowAlert(Alert.AlertType.ERROR, "FTP Error", "FTP Configuration Error", "FTP Configuration is incorrect, please check your FTP Configuration");
}
}

View File

@@ -639,7 +639,7 @@ public class Cameradetail_Arducam {
Capturing.set(false);
if (mGrabber!=null){
try{
mGrabber.stop();
mGrabber.close();
Platform.runLater(()->setCameraStatus("Camera Stopped"));
} catch (Exception e){
if (event!=null) event.onLog("StopLiveView failed, Unable to Stop Camera, Error: " + e.getMessage());

View File

@@ -3,6 +3,7 @@
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<AnchorPane fx:id="CaptureViewAnchor" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="768.0" prefWidth="1024.0" xmlns="http://javafx.com/javafx/11.0.14-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="id.co.gtc.erhacam.CaptureView">
<children>
@@ -35,109 +36,78 @@
</rowConstraints>
<children>
<AnchorPane fx:id="controlpane" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1">
<children>
<VBox layoutX="108.0" layoutY="14.0" prefHeight="256.0" prefWidth="512.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<GridPane>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="30.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<AnchorPane prefHeight="200.0" prefWidth="200.0">
<children>
<Label layoutX="28.0" layoutY="8.0" prefHeight="30.0" prefWidth="154.0" text="Save Directory" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0" />
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="1">
<children>
<Label layoutX="31.0" layoutY="6.0" prefHeight="30.0" prefWidth="154.0" text="Nomor Barcode" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0" />
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1">
<children>
<TextArea fx:id="directorypath" editable="false" layoutX="14.0" layoutY="-86.0" prefHeight="114.0" prefWidth="358.0" promptText="Directory to save Photos" wrapText="true" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0" />
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="1">
<children>
<TextArea fx:id="barcodeData" editable="false" layoutX="-21.0" layoutY="-85.0" prefHeight="115.0" prefWidth="358.0" promptText="barcode read result" wrapText="true" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0" />
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="2">
<children>
<Label layoutX="63.0" layoutY="6.0" prefHeight="30.4" prefWidth="154.4" text="Medical Record ID" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0" />
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="3">
<children>
<Label layoutX="63.0" layoutY="5.0" prefHeight="30.4" prefWidth="154.4" text="Patient Name" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0" />
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="2">
<children>
<TextArea fx:id="medicalRecordID" editable="false" layoutX="14.0" layoutY="-84.0" prefHeight="116.0" prefWidth="358.4" promptText="medical record ID" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0" />
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="3">
<children>
<TextArea fx:id="PatientName" editable="false" layoutX="-21.0" layoutY="-84.0" prefHeight="116.0" prefWidth="358.4" promptText="patient name" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0" />
</children>
</AnchorPane>
</children>
<VBox.margin>
<Insets bottom="5.0" top="5.0" />
</VBox.margin>
</GridPane>
<GridPane>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<AnchorPane prefHeight="200.0" prefWidth="200.0">
<children>
<Button layoutX="42.0" layoutY="14.0" mnemonicParsing="false" onAction="#ChangeDirectory" prefHeight="70.0" prefWidth="171.0" text="Change Directory" wrapText="true" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1">
<children>
<Button fx:id="btnAutoFocus" layoutX="72.0" layoutY="35.0" mnemonicParsing="false" onAction="#AutoFocus" prefHeight="70.0" prefWidth="171.0" text="Auto Focus" wrapText="true" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2">
<children>
<Button fx:id="btnTakePhoto" layoutX="59.0" layoutY="23.0" mnemonicParsing="false" onAction="#TakePhotos" prefHeight="70.0" prefWidth="170.0" text="Take Photos" wrapText="true" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
</children>
<VBox.margin>
<Insets top="5.0" />
</VBox.margin>
</GridPane>
</children>
</VBox>
</children>
<padding>
<Insets top="5.0" />
</padding></AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0">
<children>
<ScrollPane prefHeight="200.0" prefWidth="512.0" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0">
<content>
<AnchorPane fx:id="progressanchor" />
</content>
</ScrollPane>
<GridPane layoutX="68.0" layoutY="14.0" prefHeight="175.2" prefWidth="512.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="30.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<AnchorPane prefHeight="200.0" prefWidth="200.0">
<children>
<Label layoutX="31.0" layoutY="6.0" prefHeight="30.0" prefWidth="154.0" text="Nomor Barcode" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0">
<font>
<Font size="14.0" />
</font>
</Label>
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="1">
<children>
<Label layoutX="63.0" layoutY="6.0" prefHeight="30.4" prefWidth="154.4" text="Medical Record ID" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0">
<font>
<Font size="14.0" />
</font>
</Label>
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="2">
<children>
<Label layoutX="63.0" layoutY="5.0" prefHeight="30.4" prefWidth="154.4" text="Patient Name" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0">
<font>
<Font size="14.0" />
</font>
</Label>
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1">
<children>
<TextArea fx:id="barcodeData" editable="false" layoutX="-21.0" layoutY="-85.0" prefHeight="115.0" prefWidth="358.0" promptText="barcode read result" wrapText="true" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0">
<font>
<Font size="18.0" />
</font>
</TextArea>
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="1">
<children>
<TextArea fx:id="medicalRecordID" editable="false" layoutX="14.0" layoutY="-84.0" prefHeight="116.0" prefWidth="358.4" promptText="medical record ID" wrapText="true" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0">
<font>
<Font size="18.0" />
</font>
</TextArea>
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="2">
<children>
<TextArea fx:id="PatientName" editable="false" layoutX="-21.0" layoutY="-84.0" prefHeight="116.0" prefWidth="358.4" promptText="patient name" wrapText="true" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0">
<font>
<Font size="18.0" />
</font>
</TextArea>
</children>
</AnchorPane>
</children>
</GridPane>
</children></AnchorPane>
</children>
</GridPane>

View File

@@ -15,121 +15,21 @@
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="200.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="200.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="40.0" prefHeight="40.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<AnchorPane prefHeight="200.0" prefWidth="200.0">
<children>
<Label alignment="CENTER" layoutX="44.0" layoutY="7.0" text="Audio Setting" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="2">
<children>
<Label alignment="CENTER" layoutX="195.0" layoutY="7.0" text="Camera Setting" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="4">
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="2">
<children>
<Label alignment="CENTER" layoutX="239.0" layoutY="8.0" text="FTP Setting" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="1">
<children>
<GridPane layoutX="149.0" layoutY="-29.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="15.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="15.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<AnchorPane prefHeight="200.0" prefWidth="200.0">
<children>
<Label layoutX="62.0" layoutY="8.0" text="Phase 1 File" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="1">
<children>
<Label layoutX="49.0" layoutY="8.0" prefHeight="30.4" prefWidth="180.0" text="Phase 2 File" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="2">
<children>
<Label layoutX="62.0" layoutY="5.0" prefHeight="30.4" prefWidth="180.0" text="Phase 3 File" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="3">
<children>
<Label layoutX="22.0" layoutY="6.0" prefHeight="30.4" prefWidth="180.0" text="Phase 4 File" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="4">
<children>
<Label layoutX="34.0" layoutY="6.0" prefHeight="30.4" prefWidth="180.0" text="Phase 5 File" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1">
<children>
<TextField fx:id="AudioPhase1" layoutX="14.0" layoutY="4.0" prefHeight="30.4" prefWidth="329.6" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="1">
<children>
<TextField fx:id="AudioPhase2" layoutX="-32.0" layoutY="1.0" prefHeight="30.4" prefWidth="329.6" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="2">
<children>
<TextField fx:id="AudioPhase3" layoutY="2.0" prefHeight="30.4" prefWidth="329.6" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="3">
<children>
<TextField fx:id="AudioPhase4" layoutX="51.0" layoutY="2.0" prefHeight="30.4" prefWidth="329.6" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="4">
<children>
<TextField fx:id="AudioPhase5" layoutX="14.0" layoutY="2.0" prefHeight="30.4" prefWidth="329.6" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2">
<children>
<Button layoutX="14.0" layoutY="3.0" mnemonicParsing="false" onAction="#BrowseAudioPhase1" prefHeight="30.4" prefWidth="90.4" text="Browse" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2" GridPane.rowIndex="1">
<children>
<Button layoutX="19.0" layoutY="4.0" mnemonicParsing="false" onAction="#BrowseAudioPhase2" prefHeight="30.4" prefWidth="90.4" text="Browse" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2" GridPane.rowIndex="2">
<children>
<Button layoutX="19.0" layoutY="4.0" mnemonicParsing="false" onAction="#BrowseAudioPhase3" prefHeight="30.4" prefWidth="90.4" text="Browse" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2" GridPane.rowIndex="3">
<children>
<Button layoutX="14.0" layoutY="14.0" mnemonicParsing="false" onAction="#BrowseAudioPhase4" prefHeight="40.0" prefWidth="90.4" text="Browse" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2" GridPane.rowIndex="4">
<children>
<Button layoutY="4.0" mnemonicParsing="false" onAction="#BrowseAudioPhase5" prefHeight="30.4" prefWidth="90.4" text="Browse" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
</children>
</AnchorPane>
</children>
</GridPane>
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="3">
<children>
<GridPane AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
@@ -311,7 +211,7 @@
</GridPane>
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="5">
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="3">
<children>
<HBox prefHeight="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
@@ -389,6 +289,42 @@
</HBox>
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="4">
<children>
<Label alignment="CENTER" layoutX="287.0" prefHeight="30.4" prefWidth="1024.0" text="Directory Setting" textAlignment="CENTER" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="5">
<children>
<GridPane layoutX="75.0" layoutY="-31.0" prefHeight="40.0" prefWidth="1024.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="15.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<AnchorPane>
<children>
<Label text="Photo Save" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
<AnchorPane GridPane.columnIndex="1">
<children>
<TextField fx:id="PhotoDirectoryPath" editable="false" prefHeight="40.0" prefWidth="870.4" promptText="directory to save photo" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
</children>
</AnchorPane>
<AnchorPane GridPane.columnIndex="2">
<children>
<Button mnemonicParsing="false" onAction="#ChangePhotoDirectoryPath" prefHeight="40.0" prefWidth="102.4" text="Browse" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
</children>
</AnchorPane>
</children>
</GridPane>
</children>
</AnchorPane>
</children>
</GridPane>
</children>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
voices/kesalahan_server.wav Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
voices/tahan_posisi.wav Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.