Commit 21032025
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()));
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 = "";
|
||||
|
||||
99
src/main/java/id/co/gtc/erhacam/AutoCloseAlert.java
Normal file
99
src/main/java/id/co/gtc/erhacam/AutoCloseAlert.java
Normal 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();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
raise_log("Unable to Grab Frame, Error: " + e.getMessage());
|
||||
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);
|
||||
System.out.println("scaleXBest = "+scaleXBest+" scaleYBest = "+scaleYBest);
|
||||
System.out.println("BestMatROI camera "+cameratitle.getText()+" = "+RectToString(BestMatROI));
|
||||
|
||||
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);
|
||||
System.out.println("scaleXReduced = "+scaleXReduced+" scaleYReduced = "+scaleYReduced);
|
||||
System.out.println("ReducedMatROI camera "+cameratitle.getText()+" = "+RectToString(ReducedMatROI));
|
||||
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());
|
||||
|
||||
@@ -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,120 +373,118 @@ 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 (ValidFile(p1.getFullcrop())){
|
||||
// ada crop
|
||||
prc.setCroppedLeft90(p1.getFullcrop());
|
||||
} else {
|
||||
String xx = image1.CropBestMat(directory,prefix, bestroi);
|
||||
if (ValidFile(xx)) prc.setCroppedLeft90(xx);
|
||||
}
|
||||
if (ValidFile(p2.getFullcrop())){
|
||||
// ada crop
|
||||
prc.setCroppedLeft45(p2.getFullcrop());
|
||||
} else {
|
||||
String xx = image2.CropBestMat(directory,prefix, bestroi);
|
||||
if (ValidFile(xx)) prc.setCroppedLeft45(xx);
|
||||
}
|
||||
if (ValidFile(p3.getFullcrop())){
|
||||
// ada crop
|
||||
prc.setCroppedCenter(p3.getFullcrop());
|
||||
} else {
|
||||
String xx = image3.CropBestMat(directory,prefix, bestroi);
|
||||
if (ValidFile(xx)) prc.setCroppedCenter(xx);
|
||||
}
|
||||
if (ValidFile(p4.getFullcrop())){
|
||||
// ada crop
|
||||
prc.setCroppedRight45(p4.getFullcrop());
|
||||
} else {
|
||||
String xx = image4.CropBestMat(directory,prefix, bestroi);
|
||||
if (ValidFile(xx)) prc.setCroppedRight45(xx);
|
||||
}
|
||||
if (ValidFile(p5.getFullcrop())){
|
||||
// ada crop
|
||||
prc.setCroppedRight90(p5.getFullcrop());
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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());
|
||||
} else {
|
||||
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());
|
||||
} else {
|
||||
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());
|
||||
} else {
|
||||
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());
|
||||
} else {
|
||||
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());
|
||||
} else {
|
||||
String xx = image5.CropBestMat(directory,prefix, bestroi);
|
||||
if (ValidFile(xx)) prc.setCroppedRight90(xx);
|
||||
}
|
||||
if (ValidFile(p5.getCompressedcrop())){
|
||||
prc.setCompressedCropRight90(p5.getCompressedcrop());
|
||||
} else {
|
||||
String xx= image5.CropReducedMat(directory,prefix, reducedroi);
|
||||
if (ValidFile(xx)) prc.setCompressedCropRight90(xx);
|
||||
}
|
||||
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);
|
||||
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();
|
||||
audioPlayer.PlayFile(audio_upload_berhasil, ps);
|
||||
} 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();
|
||||
audioPlayer.PlayFile(audio_upload_gagal, ps);
|
||||
} 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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
|
||||
@@ -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;
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -14,122 +14,22 @@
|
||||
<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="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="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>
|
||||
|
||||
Reference in New Issue
Block a user