diff --git a/MyBox/pom.xml b/MyBox/pom.xml index ecf9cef9b..8410c63cc 100644 --- a/MyBox/pom.xml +++ b/MyBox/pom.xml @@ -4,7 +4,7 @@ mara MyBox - 4.8 + 4.9 jar MyBox diff --git a/MyBox/src/main/java/mara/mybox/MainApp.java b/MyBox/src/main/java/mara/mybox/MainApp.java index 921ba4d15..82f216240 100644 --- a/MyBox/src/main/java/mara/mybox/MainApp.java +++ b/MyBox/src/main/java/mara/mybox/MainApp.java @@ -6,13 +6,14 @@ import javafx.application.Platform; import javafx.stage.Stage; import javax.imageio.ImageIO; -import mara.mybox.controller.OpenFile; +import mara.mybox.controller.BaseController; +import mara.mybox.fxml.FxmlStage; import mara.mybox.db.DerbyBase; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.CommonValues; -import mara.mybox.image.ImageValueTools; +import mara.mybox.value.AppVaribles; +import mara.mybox.value.CommonValues; +import mara.mybox.image.ImageValue; import mara.mybox.tools.FileTools; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.logger; /** * @Author Mara @@ -30,24 +31,29 @@ public void start(Stage stage) throws Exception { System.setProperty("sun.java2d.cmm", "sun.java2d.cmm.kcms.KcmsServiceProvider"); System.setProperty("org.apache.pdfbox.rendering.UsePureJavaCMYKConversion", "true"); - ImageValueTools.registrySupportedImageFormats(); - - File userPath = new File(CommonValues.UserFilePath); + File userPath = new File(CommonValues.AppDataRoot); if (!userPath.exists()) { - userPath.mkdirs(); + if (!userPath.mkdirs()) { + FxmlStage.alertError(stage, "Can not find or make user path:\n" + CommonValues.AppDataRoot); + return; + } + } + if (CommonValues.AppTempPath.exists()) { + FileTools.deleteDir(CommonValues.AppTempPath); + } + if (!CommonValues.AppTempPath.mkdirs()) { + FxmlStage.alertError(stage, "Can not find or make user path:\n" + CommonValues.AppTempPath); + return; } + + // The following 3 statements should be done in this order DerbyBase.initTables(); AppVaribles.initAppVaribles(); DerbyBase.checkUpdates(); - File tempPath = new File(CommonValues.TempPath); - if (tempPath.exists()) { - FileTools.deleteDir(tempPath); - } - tempPath.mkdirs(); - + ImageValue.registrySupportedImageFormats(); ImageIO.setUseCache(true); - ImageIO.setCacheDirectory(new File(CommonValues.TempPath)); + ImageIO.setCacheDirectory(CommonValues.AppTempPath); String inFile = null; List paremeters = getParameters().getUnnamed(); @@ -57,11 +63,12 @@ public void start(Stage stage) throws Exception { } } if (inFile != null) { - if (!OpenFile.openTarget(getClass(), stage, inFile)) { - OpenFile.openMyBox(getClass(), stage); + BaseController controller = FxmlStage.openTarget(getClass(), stage, inFile, false); + if (controller == null) { + FxmlStage.openMyBox(getClass(), stage); } } else { - OpenFile.openMyBox(getClass(), stage); + FxmlStage.openMyBox(getClass(), stage); } // https://stackoverflow.com/questions/23527679/trying-to-open-a-javafx-stage-after-calling-platform-exit diff --git a/MyBox/src/main/java/mara/mybox/controller/AboutController.java b/MyBox/src/main/java/mara/mybox/controller/AboutController.java index d3be18364..eaaf78454 100644 --- a/MyBox/src/main/java/mara/mybox/controller/AboutController.java +++ b/MyBox/src/main/java/mara/mybox/controller/AboutController.java @@ -5,10 +5,10 @@ import javafx.fxml.FXML; import javafx.scene.control.Hyperlink; import javafx.scene.control.Label; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.CommonValues; +import mara.mybox.value.AppVaribles; +import mara.mybox.value.CommonValues; import mara.mybox.fxml.FxmlTools; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.logger; /** * @Author Mara diff --git a/MyBox/src/main/java/mara/mybox/controller/AlarmClockController.java b/MyBox/src/main/java/mara/mybox/controller/AlarmClockController.java index 89f9b0151..b015510f1 100644 --- a/MyBox/src/main/java/mara/mybox/controller/AlarmClockController.java +++ b/MyBox/src/main/java/mara/mybox/controller/AlarmClockController.java @@ -26,12 +26,12 @@ import javax.sound.sampled.FloatControl; import javax.sound.sampled.LineEvent; import javax.sound.sampled.LineListener; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.AlarmClock; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.CommonValues; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.data.AlarmClock; +import mara.mybox.value.AppVaribles; +import mara.mybox.value.CommonValues; import mara.mybox.tools.SoundTools; -import static mara.mybox.objects.AppVaribles.getMessage; +import static mara.mybox.value.AppVaribles.getMessage; import mara.mybox.tools.DateTools; import mara.mybox.fxml.FxmlTools; import static mara.mybox.fxml.FxmlTools.badStyle; @@ -53,7 +53,7 @@ public class AlarmClockController extends BaseController { @FXML private CheckBox activeCheck, loopCheck; @FXML - private Button playButton, pauseButton, saveButton; + private Button playButton, pauseButton; @FXML protected Pane alertClockTable; @FXML @@ -474,12 +474,14 @@ public void handle(ActionEvent event) { private void selectSound(ActionEvent event) { try { final FileChooser fileChooser = new FileChooser(); - String defaultPath = CommonValues.UserFilePath; + String defaultPath = CommonValues.AppDataRoot; if (System.getProperty("os.name").toLowerCase().contains("windows")) { defaultPath = "C:\\Windows\\media"; } - File path = new File(AppVaribles.getUserConfigPath(SystemMediaPathKey, defaultPath)); - fileChooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(SystemMediaPathKey, defaultPath); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("wav", "*.wav")); final File file = fileChooser.showOpenDialog(getMyStage()); if (file == null) { @@ -500,8 +502,10 @@ private void selectSound(ActionEvent event) { private void selectMusic(ActionEvent event) { try { final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(MusicPathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(MusicPathKey); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("mp3", "*.mp3")); final File file = fileChooser.showOpenDialog(getMyStage()); if (file == null) { @@ -519,7 +523,8 @@ private void selectMusic(ActionEvent event) { } @FXML - private void saveAlarm(ActionEvent event) { + @Override + public void saveAction() { if (currentAlarm == null || !isEdit) { currentAlarm = new AlarmClock(); currentAlarm.setKey(new Date().getTime()); diff --git a/MyBox/src/main/java/mara/mybox/controller/AlarmClockRunController.java b/MyBox/src/main/java/mara/mybox/controller/AlarmClockRunController.java index ab39a7405..15876138d 100644 --- a/MyBox/src/main/java/mara/mybox/controller/AlarmClockRunController.java +++ b/MyBox/src/main/java/mara/mybox/controller/AlarmClockRunController.java @@ -6,12 +6,12 @@ import javafx.fxml.FXML; import javafx.scene.control.Label; import javax.sound.sampled.Clip; -import mara.mybox.objects.AlarmClock; -import static mara.mybox.objects.AlarmClock.getTypeString; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.CommonValues; +import mara.mybox.data.AlarmClock; +import static mara.mybox.data.AlarmClock.getTypeString; +import mara.mybox.value.AppVaribles; +import mara.mybox.value.CommonValues; import mara.mybox.fxml.FxmlTools; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.logger; import mara.mybox.tools.SoundTools; /** diff --git a/MyBox/src/main/java/mara/mybox/controller/AlarmClockTableController.java b/MyBox/src/main/java/mara/mybox/controller/AlarmClockTableController.java index 791a7521d..9269878a0 100644 --- a/MyBox/src/main/java/mara/mybox/controller/AlarmClockTableController.java +++ b/MyBox/src/main/java/mara/mybox/controller/AlarmClockTableController.java @@ -18,9 +18,10 @@ import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.input.MouseEvent; import javafx.scene.layout.HBox; -import mara.mybox.objects.AlarmClock; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.logger; +import javafx.scene.layout.Region; +import mara.mybox.data.AlarmClock; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.logger; import mara.mybox.tools.DateTools; /** @@ -124,6 +125,7 @@ private void clearAction(ActionEvent event) { Alert alert = new Alert(Alert.AlertType.CONFIRMATION); alert.setTitle(getBaseTitle()); alert.setContentText(AppVaribles.getMessage("SureClearAlarmClocks")); + alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); Optional result = alert.showAndWait(); if (result.get() != ButtonType.OK) { return; @@ -138,7 +140,8 @@ private void clearAction(ActionEvent event) { } @FXML - private void deleteAction(ActionEvent event) { + @Override + public void deleteAction() { ObservableList selected = alarmClocksView.getSelectionModel().getSelectedItems(); if (selected == null || selected.isEmpty()) { return; diff --git a/MyBox/src/main/java/mara/mybox/controller/BaseController.java b/MyBox/src/main/java/mara/mybox/controller/BaseController.java index 809a57266..aa63888f2 100644 --- a/MyBox/src/main/java/mara/mybox/controller/BaseController.java +++ b/MyBox/src/main/java/mara/mybox/controller/BaseController.java @@ -1,5 +1,6 @@ package mara.mybox.controller; +import mara.mybox.fxml.FxmlStage; import java.awt.Desktop; import java.io.File; import java.net.URL; @@ -9,7 +10,6 @@ import java.util.ResourceBundle; import java.util.Timer; import java.util.TimerTask; -import java.util.concurrent.ScheduledFuture; import javafx.application.Platform; import javafx.beans.binding.Bindings; import javafx.beans.value.ChangeListener; @@ -30,10 +30,13 @@ import javafx.scene.control.CheckBox; import javafx.scene.control.Label; import javafx.scene.control.TextField; +import javafx.scene.control.Tooltip; import javafx.scene.image.Image; import javafx.scene.input.KeyEvent; import javafx.scene.layout.Pane; +import javafx.scene.layout.Region; import javafx.scene.layout.VBox; +import javafx.scene.text.Font; import javafx.stage.DirectoryChooser; import javafx.stage.FileChooser; import javafx.stage.Modality; @@ -42,16 +45,16 @@ import javafx.stage.StageStyle; import javafx.stage.WindowEvent; import mara.mybox.db.DerbyBase; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.FileInformation; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.value.CommonValues; +import mara.mybox.data.FileInformation; import mara.mybox.tools.FileTools; import mara.mybox.fxml.FxmlTools; import static mara.mybox.fxml.FxmlTools.badStyle; -import static mara.mybox.objects.AppVaribles.logger; -import static mara.mybox.objects.CommonValues.UserFilePath; -import mara.mybox.objects.ImageInformation; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.data.ImageInformation; +import static mara.mybox.value.CommonValues.AppDataRoot; /** * @Author Mara @@ -61,6 +64,8 @@ */ public class BaseController implements Initializable { + protected String TipsLabelKey; + protected List fileExtensionFilter; protected String myFxml, parentFxml, currentStatus, baseTitle; @@ -71,7 +76,7 @@ public class BaseController implements Initializable { protected Timer popupTimer, timer; protected Popup popup; - protected boolean isPreview, targetIsFile, paused; + protected boolean isPreview, targetIsFile, paused, isSettingValues; protected File sourceFile, targetPath; protected List sourceFiles; protected ObservableList sourceFilesInformation; @@ -95,7 +100,9 @@ public class BaseController implements Initializable { @FXML protected OperationController operationBarController; @FXML - protected Button previewButton; + protected Button newButton, copyButton, deleteButton, saveButton, infoButton, selectAllButton, + imageSizeButton, paneSizeButton, zoomInButton, zoomOutButton, okButton, startButton, + firstButton, lastButton, previousButton, nextButton, previewButton; @FXML protected VBox paraBox; @FXML @@ -103,7 +110,7 @@ public class BaseController implements Initializable { @FXML protected CheckBox fillZero, subdirCheck, appendDensity, appendColor, appendCompressionType, appendQuality, appendSize; @FXML - protected Label bottomLabel; + protected Label bottomLabel, tipsLabel; public BaseController() { LastPathKey = "LastPathKey"; @@ -139,6 +146,7 @@ public void initialize(URL url, ResourceBundle rb) { } if (thisPane != null) { + thisPane.setStyle("-fx-font-size: " + AppVaribles.getPaneFontSize() + "px;"); thisPane.setOnKeyReleased(new EventHandler() { @Override public void handle(KeyEvent event) { @@ -147,6 +155,117 @@ public void handle(KeyEvent event) { }); } + setTips(); + initInputs(); + + initializeNext(); + } catch (Exception e) { + logger.error(e.toString()); + } + } + + protected void setTips() { + + if (tipsLabel != null && TipsLabelKey != null) { + Tooltip tips = new Tooltip(getMessage(TipsLabelKey)); + tips.setFont(new Font(16)); + FxmlTools.quickTooltip(tipsLabel, tips); + } + + if (okButton != null) { + Tooltip tips = new Tooltip("CTRL+g"); + tips.setFont(new Font(16)); + FxmlTools.quickTooltip(okButton, tips); + } + + if (newButton != null) { + Tooltip tips = new Tooltip("CTRL+n"); + tips.setFont(new Font(16)); + FxmlTools.quickTooltip(newButton, tips); + } + + if (deleteButton != null) { + Tooltip tips = new Tooltip("CTRL+d / DELETE"); + tips.setFont(new Font(16)); + FxmlTools.quickTooltip(deleteButton, tips); + } + + if (copyButton != null) { + Tooltip tips = new Tooltip("CTRL+c"); + tips.setFont(new Font(16)); + FxmlTools.quickTooltip(copyButton, tips); + } + + if (saveButton != null) { + Tooltip tips = new Tooltip("CTRL+s"); + tips.setFont(new Font(16)); + FxmlTools.quickTooltip(saveButton, tips); + + } + + if (infoButton != null) { + Tooltip tips = new Tooltip("CTRL+i"); + tips.setFont(new Font(16)); + FxmlTools.quickTooltip(infoButton, tips); + } + + if (selectAllButton != null) { + Tooltip tips = new Tooltip("CTRL+a"); + tips.setFont(new Font(16)); + FxmlTools.quickTooltip(selectAllButton, tips); + } + + if (nextButton != null) { + Tooltip tips = new Tooltip("PAGE DOWN"); + tips.setFont(new Font(16)); + FxmlTools.quickTooltip(nextButton, tips); + } + if (previousButton != null) { + Tooltip tips = new Tooltip("PAGE UP"); + tips.setFont(new Font(16)); + FxmlTools.quickTooltip(previousButton, tips); + } + if (firstButton != null) { + Tooltip tips = new Tooltip("HOME"); + tips.setFont(new Font(16)); + FxmlTools.quickTooltip(firstButton, tips); + } + if (lastButton != null) { + Tooltip tips = new Tooltip("END"); + tips.setFont(new Font(16)); + FxmlTools.quickTooltip(lastButton, tips); + } + + if (imageSizeButton != null) { + Tooltip tips = new Tooltip("CTRL+1"); + tips.setFont(new Font(16)); + FxmlTools.quickTooltip(imageSizeButton, tips); + } + + if (paneSizeButton != null) { + Tooltip tips = new Tooltip("CTRL+2"); + tips.setFont(new Font(16)); + FxmlTools.quickTooltip(paneSizeButton, tips); + + } + + if (zoomInButton != null) { + Tooltip tips = new Tooltip("CTRL+3"); + tips.setFont(new Font(16)); + FxmlTools.quickTooltip(zoomInButton, tips); + + } + + if (zoomOutButton != null) { + Tooltip tips = new Tooltip("CTRL+4"); + tips.setFont(new Font(16)); + FxmlTools.quickTooltip(zoomOutButton, tips); + } + } + + protected void initInputs() { + try { + if (sourceFileInput != null) { sourceFileInput.textProperty().addListener(new ChangeListener() { @Override @@ -171,7 +290,7 @@ public void changed(ObservableValue observable, String oldValu } else { AppVaribles.setUserConfigValue(sourcePathKey, file.getParent()); if (targetPathInput != null && targetPathInput.getText().isEmpty()) { - targetPathInput.setText(AppVaribles.getUserConfigValue(targetPathKey, CommonValues.UserFilePath)); + targetPathInput.setText(AppVaribles.getUserConfigPath(targetPathKey).getAbsolutePath()); } if (targetPrefixInput != null) { targetPrefixInput.setText(FileTools.getFilePrefix(file.getName())); @@ -218,7 +337,7 @@ public void changed(ObservableValue observable, String oldValu } } }); - targetSelectionController.targetPathInput.setText(AppVaribles.getUserConfigValue(targetPathKey, CommonValues.UserFilePath)); + targetSelectionController.targetPathInput.setText(AppVaribles.getUserConfigPath(targetPathKey).getAbsolutePath()); } } @@ -270,22 +389,126 @@ public void changed(ObservableValue observable, String oldValu acumFromInput.setText("1"); } - initializeNext(); } catch (Exception e) { logger.error(e.toString()); } } protected void keyEventsHandler(KeyEvent event) { - String key = event.getText(); - if (key == null || key.isEmpty()) { - return; - } if (event.isControlDown()) { - if ("m".equals(key) || "M".equals(key)) { // ctrl-m - if (mainMenuController != null) { - mainMenuController.getShowCommentsCheck().setSelected(!mainMenuController.getShowCommentsCheck().isSelected()); - mainMenuController.checkShowComments(); + String key = event.getText(); + if (key == null || key.isEmpty()) { + return; + } + switch (key) { + case "n": + case "N": + if (newButton != null && !newButton.isDisabled()) { + newAction(); + } + break; + case "g": + case "G": + if (okButton != null && !okButton.isDisabled()) { + okAction(); + } + break; + case "c": + case "C": + if (copyButton != null && !copyButton.isDisabled()) { + copyAction(); + } + break; + case "s": + case "S": + if (saveButton != null && !saveButton.isDisabled()) { + saveAction(); + } + break; + case "i": + case "I": + if (infoButton != null && !infoButton.isDisabled()) { + infoAction(); + } + break; + case "d": + case "D": + if (deleteButton != null && !deleteButton.isDisabled()) { + deleteAction(); + } + break; + case "a": + case "A": + if (selectAllButton != null && !selectAllButton.isDisabled()) { + selectAllAction(); + } + break; + case "m": + case "M": + if (mainMenuController != null) { + mainMenuController.getShowCommentsCheck().setSelected(!mainMenuController.getShowCommentsCheck().isSelected()); + mainMenuController.checkShowComments(); + } + break; + case "1": + if (imageSizeButton != null && !imageSizeButton.isDisabled()) { + imageSize(); + } + break; + case "2": + if (paneSizeButton != null && !paneSizeButton.isDisabled()) { + paneSize(); + } + break; + case "3": + if (zoomInButton != null && !zoomInButton.isDisabled()) { + zoomIn(); + } + break; + case "4": + if (zoomOutButton != null && !zoomOutButton.isDisabled()) { + zoomOut(); + } + break; + case "-": + setPaneFontSize(AppVaribles.getPaneFontSize() - 1); + break; + case "=": + setPaneFontSize(AppVaribles.getPaneFontSize() + 1); + break; + } + + } else { + if (null != event.getCode()) { + switch (event.getCode()) { + case DELETE: + if (deleteButton != null && !deleteButton.isDisabled()) { + deleteAction(); + } + break; + case HOME: + if (firstButton != null && !firstButton.isDisabled()) { + firstAction(); + } + break; + case END: + if (lastButton != null && !lastButton.isDisabled()) { + lastAction(); + } + break; + case PAGE_UP: + if (previousButton != null && !previousButton.isDisabled()) { + previousAction(); + } + break; + case PAGE_DOWN: + if (nextButton != null && !nextButton.isDisabled()) { + nextAction(); + } + break; + case F5: + closeStage(); + break; } } } @@ -319,12 +542,39 @@ public void setInterfaceStyle(String style) { } } + protected boolean setPaneFontSize(int size) { + if (thisPane == null || size < 9 || size > 22 + || size == AppVaribles.getPaneFontSize()) { + return false; + } + AppVaribles.setPaneFontSize(size); + thisPane.setStyle("-fx-font-size: " + size + "px;"); + if (parentController != null && parentController.getThisPane() != null) { + parentController.getThisPane().setStyle("-fx-font-size: " + size + "px;"); + } + return true; + } + + public void refresh() { + if (parentController != null) { + parentController.refresh(); + } + if (myFxml.contains("ImageManufacture") && !myFxml.contains("ImageManufactureBatch")) { + reloadStage(CommonValues.ImageManufactureFileFxml, getParentController().getMyStage().getTitle()); + } else { + reloadStage(myFxml, getBaseTitle()); + } + + } + @FXML protected void selectSourceFile(ActionEvent event) { try { final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(sourcePathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(sourcePathKey); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } fileChooser.getExtensionFilters().addAll(fileExtensionFilter); File file = fileChooser.showOpenDialog(getMyStage()); if (file == null) { @@ -355,8 +605,10 @@ protected void selectTargetPath(ActionEvent event) { } try { DirectoryChooser chooser = new DirectoryChooser(); - File path = new File(AppVaribles.getUserConfigPath(targetPathKey, CommonValues.UserFilePath)); - chooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(targetPathKey); + if (path != null) { + chooser.setInitialDirectory(path); + } File directory = chooser.showDialog(getMyStage()); if (directory == null) { return; @@ -382,7 +634,7 @@ protected void openTarget(ActionEvent event) { } if (targetIsFile && finalTargetName != null) { - OpenFile.openTarget(getClass(), null, finalTargetName); + FxmlStage.openTarget(getClass(), null, finalTargetName); } else { if (targetSelectionController.targetPathInput != null) { @@ -411,7 +663,83 @@ protected void openTarget(ActionEvent event) { } @FXML - protected void startProcess(ActionEvent event) { + public void okAction() { + + } + + @FXML + public void startAction() { + + } + + @FXML + public void newAction() { + + } + + @FXML + public void copyAction() { + + } + + @FXML + public void saveAction() { + + } + + @FXML + public void deleteAction() { + + } + + @FXML + public void infoAction() { + + } + + @FXML + public void selectAllAction() { + + } + + @FXML + public void nextAction() { + + } + + @FXML + public void previousAction() { + + } + + @FXML + public void firstAction() { + + } + + @FXML + public void lastAction() { + + } + + @FXML + public void imageSize() { + + } + + @FXML + public void paneSize() { + + } + + @FXML + public void zoomIn() { + + } + + @FXML + public void zoomOut() { + } @FXML @@ -444,20 +772,62 @@ protected void clearSettings(ActionEvent event) { Alert alert = new Alert(Alert.AlertType.CONFIRMATION); alert.setTitle(getBaseTitle()); alert.setContentText(AppVaribles.getMessage("SureClear")); + alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); Optional result = alert.showAndWait(); if (result.get() != ButtonType.OK) { return; } DerbyBase.clearData(); - clearTempFiles(); + cleanAppPath(); AppVaribles.initAppVaribles(); popInformation(AppVaribles.getMessage("Successful")); } + protected void cleanAppPath() { + try { + File userPath = new File(AppDataRoot); + if (userPath.exists()) { + File[] files = userPath.listFiles(); + for (File f : files) { + if (f.isFile()) { + f.delete(); + } else if (!CommonValues.AppDataPaths.contains(f)) { + FileTools.deleteDir(f); + } + } + } + } catch (Exception e) { + logger.error(e.toString()); + } + } + + protected void clearUserTempFiles() { + try { + File tempPath = AppVaribles.getUserTempPath(); + if (tempPath.exists()) { + FileTools.deleteDir(tempPath); + } + } catch (Exception e) { + logger.error(e.toString()); + } + } + + protected void clearSystemTempFiles() { + try { + if (CommonValues.AppTempPath.exists()) { + FileTools.deleteDir(CommonValues.AppTempPath); + } else { + CommonValues.AppTempPath.mkdirs(); + } + } catch (Exception e) { + logger.error(e.toString()); + } + } + @FXML protected void openUserPath(ActionEvent event) { try { - Desktop.getDesktop().browse(new File(UserFilePath).toURI()); + Desktop.getDesktop().browse(new File(AppDataRoot).toURI()); } catch (Exception e) { logger.error(e.toString()); } @@ -480,7 +850,7 @@ protected File checkHelps() { try { String lang = AppVaribles.getLanguage(); String latest = AppVaribles.getSystemConfigValue("HelpsVersion", ""); - String newVersion = "4.8"; + String newVersion = "4.9"; boolean updated = latest.equals(newVersion); if (!updated) { logger.debug("Updating Helps " + newVersion); @@ -502,7 +872,7 @@ protected File checkHelps() { protected void clearHelps() { try { - File file = new File(UserFilePath); + File file = new File(AppDataRoot); if (file.exists()) { File[] files = file.listFiles(); for (File f : files) { @@ -516,22 +886,6 @@ protected void clearHelps() { } } - protected void clearTempFiles() { - try { - File file = new File(UserFilePath); - if (file.exists()) { - File[] files = file.listFiles(); - for (File f : files) { - if (f.isFile()) { - f.delete(); - } - } - } - } catch (Exception e) { - logger.error(e.toString()); - } - } - protected void cancelProcess(ActionEvent event) { paused = false; if (task != null && task.isRunning()) { @@ -612,7 +966,7 @@ public BaseController openStage(String newFxml, boolean isOwned, boolean monitor } public BaseController openStage(String newFxml, String title, boolean isOwned, boolean monitorClosing) { - return OpenFile.openNewStage(getClass(), getMyStage(), newFxml, title, isOwned, monitorClosing); + return FxmlStage.openNewStage(getClass(), getMyStage(), newFxml, title, isOwned, monitorClosing); } public boolean closeStage() { @@ -626,9 +980,6 @@ public boolean closeStage() { public boolean stageClosing() { try { -// logger.debug("stageClosing:" + getMyStage().getWidth() + "," + myStage.getHeight()); -// logger.debug(Platform.isImplicitExit()); -// logger.debug("stageClosing:" + getClass()); hidePopup(); if (timer != null) { @@ -638,8 +989,8 @@ public boolean stageClosing() { Alert alert = new Alert(Alert.AlertType.CONFIRMATION); alert.setTitle(getMyStage().getTitle()); alert.setContentText(AppVaribles.getMessage("TaskRunning")); + alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); Optional result = alert.showAndWait(); - logger.debug(result.get()); if (result.get() == ButtonType.OK && task != null) { task.cancel(); } else { @@ -647,39 +998,13 @@ public boolean stageClosing() { } } - if (AppVaribles.scheduledTasks != null && !AppVaribles.scheduledTasks.isEmpty()) { - if (AppVaribles.getUserConfigBoolean("StopAlarmsWhenExit")) { - for (Long key : AppVaribles.scheduledTasks.keySet()) { - ScheduledFuture future = AppVaribles.scheduledTasks.get(key); - future.cancel(true); - } - AppVaribles.scheduledTasks = null; - if (AppVaribles.executorService != null) { - AppVaribles.executorService.shutdownNow(); - AppVaribles.executorService = null; - } - } - - } else { - if (AppVaribles.scheduledTasks != null) { - AppVaribles.scheduledTasks = null; - } - if (AppVaribles.executorService != null) { - AppVaribles.executorService.shutdownNow(); - AppVaribles.executorService = null; - } - } - if (backgroundTask != null && backgroundTask.isRunning()) { backgroundTask.cancel(); } - if (AppVaribles.scheduledTasks == null) { - Platform.setImplicitExit(true); - } -// logger.debug(Platform.isImplicitExit()); - return true; + Platform.setImplicitExit(AppVaribles.scheduledTasks == null); + return true; } catch (Exception e) { logger.debug(e.toString()); return false; @@ -688,39 +1013,15 @@ public boolean stageClosing() { } public void alertError(String information) { - try { - Alert alert = new Alert(Alert.AlertType.ERROR); - alert.setTitle(getMyStage().getTitle()); - alert.setHeaderText(null); - alert.setContentText(information); - alert.showAndWait(); - } catch (Exception e) { - logger.error(e.toString()); - } + FxmlStage.alertError(getMyStage(), information); } public void alertWarning(String information) { - try { - Alert alert = new Alert(Alert.AlertType.WARNING); - alert.setTitle(getMyStage().getTitle()); - alert.setHeaderText(null); - alert.setContentText(information); - alert.showAndWait(); - } catch (Exception e) { - logger.error(e.toString()); - } + FxmlStage.alertError(getMyStage(), information); } public void alertInformation(String information) { - try { - Alert alert = new Alert(Alert.AlertType.INFORMATION); - alert.setTitle(getMyStage().getTitle()); - alert.setHeaderText(null); - alert.setContentText(information); - alert.showAndWait(); - } catch (Exception e) { - logger.error(e.toString()); - } + FxmlStage.alertInformation(getMyStage(), information); } public void popInformation(String text) { @@ -843,12 +1144,12 @@ public void setMyStage(Stage myStage) { } public void openImageManufacture(String filename) { - OpenFile.openImageManufacture(getClass(), null, new File(filename)); + FxmlStage.openImageManufacture(getClass(), null, new File(filename)); } public void openImageViewer(Image image) { try { - final ImageViewerController controller = OpenFile.openImageViewer(getClass(), null); + final ImageViewerController controller = FxmlStage.openImageViewer(getClass(), null); if (controller != null) { controller.loadImage(image); } @@ -859,7 +1160,7 @@ public void openImageViewer(Image image) { public void openImageViewer(ImageInformation info) { try { - final ImageViewerController controller = OpenFile.openImageViewer(getClass(), null); + final ImageViewerController controller = FxmlStage.openImageViewer(getClass(), null); if (controller != null) { controller.loadImage(info); } @@ -869,7 +1170,7 @@ public void openImageViewer(ImageInformation info) { } public void openImageViewer(String file) { - OpenFile.openImageViewer(getClass(), null, new File(file)); + FxmlStage.openImageViewer(getClass(), null, new File(file)); } public LoadingController openHandlingStage(Modality block) { diff --git a/MyBox/src/main/java/mara/mybox/controller/BytesEditerController.java b/MyBox/src/main/java/mara/mybox/controller/BytesEditerController.java index 4ce7fdb52..84af9d003 100644 --- a/MyBox/src/main/java/mara/mybox/controller/BytesEditerController.java +++ b/MyBox/src/main/java/mara/mybox/controller/BytesEditerController.java @@ -17,9 +17,9 @@ import javafx.scene.control.Toggle; import javafx.stage.Modality; import static mara.mybox.fxml.FxmlTools.badStyle; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.FileEditInformation.Line_Break; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.data.FileEditInformation.Line_Break; import mara.mybox.tools.ByteTools; import mara.mybox.tools.StringTools; import mara.mybox.tools.TextTools; @@ -40,6 +40,8 @@ public class BytesEditerController extends FileEditerController { private RadioButton bytesNumberRadio, byteRadio; public BytesEditerController() { + TipsLabelKey = "BytesEditerTips"; + setBytesType(); } diff --git a/MyBox/src/main/java/mara/mybox/controller/ColorPaletteController.java b/MyBox/src/main/java/mara/mybox/controller/ColorPaletteController.java index 963bfcba0..bb73864b5 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ColorPaletteController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ColorPaletteController.java @@ -7,9 +7,9 @@ import javafx.scene.control.TextField; import javafx.scene.layout.HBox; import javafx.scene.paint.Color; -import static mara.mybox.fxml.FxmlColorTools.rgb2AlphaHex; -import static mara.mybox.fxml.FxmlColorTools.rgb2Hex; -import static mara.mybox.objects.AppVaribles.getMessage; +import static mara.mybox.fxml.FxmlColor.rgb2AlphaHex; +import static mara.mybox.fxml.FxmlColor.rgb2Hex; +import static mara.mybox.value.AppVaribles.getMessage; /** * @Author Mara diff --git a/MyBox/src/main/java/mara/mybox/controller/ConvolutionKernelManagerController.java b/MyBox/src/main/java/mara/mybox/controller/ConvolutionKernelManagerController.java index 7ad292fe8..175953311 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ConvolutionKernelManagerController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ConvolutionKernelManagerController.java @@ -38,16 +38,17 @@ import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; +import javafx.scene.layout.Region; import javafx.scene.layout.VBox; import javafx.stage.Modality; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.logger; import mara.mybox.db.TableConvolutionKernel; import mara.mybox.db.TableFloatMatrix; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.ConvolutionKernel; -import mara.mybox.objects.ConvolutionKernel.Convolution_Type; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.value.CommonValues; +import mara.mybox.data.ConvolutionKernel; +import mara.mybox.data.ConvolutionKernel.Convolution_Type; import mara.mybox.tools.DateTools; import mara.mybox.fxml.FxmlTools; import static mara.mybox.fxml.FxmlTools.badStyle; @@ -63,7 +64,7 @@ public class ConvolutionKernelManagerController extends BaseController { protected ObservableList tableData = FXCollections.observableArrayList(); private int width, height, type, edge_Op; - private boolean isSettingValues, matrixValid; + private boolean matrixValid; private GridPane matrixPane; private TextField[][] matrixInputs; private float[][] matrixValues; @@ -75,7 +76,7 @@ public class ConvolutionKernelManagerController extends BaseController { @FXML private SplitPane splitPane; @FXML - private Button editButton, deleteButton, saveButton, copyButton, gaussButton; + private Button editButton, gaussButton; @FXML private TableView tableView; @FXML @@ -154,11 +155,11 @@ private void loadList() { if (parentController != null && parentFxml != null) { if (parentFxml.contains("ImageManufactureConvolution")) { - ImageManufactureConvolutionController p = (ImageManufactureConvolutionController) parentController; - p.loadList(records); - } else if (parentFxml.contains("ImageManufactureBatchConvolution")) { - ImageManufactureBatchConvolutionController p = (ImageManufactureBatchConvolutionController) parentController; - p.loadList(records); + ImageManufactureEffectsController p = (ImageManufactureEffectsController) parentController; + p.loadKernelsList(records); + } else if (parentFxml.contains("ImageManufactureBatchEffects")) { + ImageManufactureBatchEffectsController p = (ImageManufactureBatchEffectsController) parentController; + p.loadKernelsList(records); } } } @@ -285,13 +286,13 @@ private void checkEdges() { if (isSettingValues) { return; } - edge_Op = ConvolutionKernel.Edge_Op.FILL_ZERO; + edge_Op = ConvolutionKernel.Edge_Op.COPY; RadioButton selected = (RadioButton) edgesGroup.getSelectedToggle(); if (selected == null) { return; } - if (getMessage("KeepValues").equals(selected.getText())) { - edge_Op = ConvolutionKernel.Edge_Op.COPY; + if (!getMessage("KeepValues").equals(selected.getText())) { + edge_Op = ConvolutionKernel.Edge_Op.FILL_ZERO; } } catch (Exception e) { logger.error(e.toString()); @@ -479,7 +480,8 @@ private void editAction() { } @FXML - private void copyAction() { + @Override + public void copyAction() { editAction(); nameInput.setDisable(false); nameInput.setText(kernel.getName() + " mmm"); @@ -487,7 +489,8 @@ private void copyAction() { } @FXML - private void deleteAction(ActionEvent event) { + @Override + public void deleteAction() { final List selected = tableView.getSelectionModel().getSelectedItems(); if (selected == null || selected.isEmpty()) { return; @@ -495,6 +498,7 @@ private void deleteAction(ActionEvent event) { Alert alert = new Alert(Alert.AlertType.CONFIRMATION); alert.setTitle(getMyStage().getTitle()); alert.setContentText(AppVaribles.getMessage("SureDelete")); + alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); ButtonType buttonSure = new ButtonType(AppVaribles.getMessage("Sure")); ButtonType buttonCancel = new ButtonType(AppVaribles.getMessage("Cancel")); alert.getButtonTypes().setAll(buttonSure, buttonCancel); @@ -538,6 +542,7 @@ private void clearAction(ActionEvent event) { Alert alert = new Alert(Alert.AlertType.CONFIRMATION); alert.setTitle(getMyStage().getTitle()); alert.setContentText(AppVaribles.getMessage("SureDelete")); + alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); ButtonType buttonSure = new ButtonType(AppVaribles.getMessage("Sure")); ButtonType buttonCancel = new ButtonType(AppVaribles.getMessage("Cancel")); alert.getButtonTypes().setAll(buttonSure, buttonCancel); @@ -689,18 +694,19 @@ private void testAction(ActionEvent event) { if (!pickKernel()) { return; } - ImageManufactureConvolutionController c - = (ImageManufactureConvolutionController) openStage(CommonValues.ImageManufactureConvolutionFxml, true); + ImageManufactureEffectsController c + = (ImageManufactureEffectsController) openStage(CommonValues.ImageManufactureEffectsFxml, false); c.setParentController(getMyController()); c.setParentFxml(getMyFxml()); c.loadImage(new Image("img/p3.png")); - c.setTab("convolution"); + c.setTab("effects"); c.showRef(); - c.selectKernel(kernel); + c.applyKernel(kernel); } @FXML - private void saveAction(ActionEvent event) { + @Override + public void saveAction() { if (!pickKernel() || name == null || name.isEmpty()) { return; } diff --git a/MyBox/src/main/java/mara/mybox/controller/DirectorySynchronizeController.java b/MyBox/src/main/java/mara/mybox/controller/DirectorySynchronizeController.java index 2569fb15d..f76c8b353 100644 --- a/MyBox/src/main/java/mara/mybox/controller/DirectorySynchronizeController.java +++ b/MyBox/src/main/java/mara/mybox/controller/DirectorySynchronizeController.java @@ -28,11 +28,10 @@ import javafx.scene.layout.VBox; import javafx.stage.DirectoryChooser; import javafx.stage.FileChooser; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.FileSynchronizeAttributes; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.data.FileSynchronizeAttributes; import mara.mybox.tools.DateTools; import mara.mybox.tools.FileTools; import mara.mybox.fxml.FxmlTools; @@ -86,7 +85,7 @@ public DirectorySynchronizeController() { protected void initializeNext() { try { - sourcePathInput.setText(AppVaribles.getUserConfigValue(sourcePathKey, CommonValues.UserFilePath)); + sourcePathInput.setText(AppVaribles.getUserConfigPath(sourcePathKey).getAbsolutePath()); sourcePathInput.textProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue observable, @@ -102,7 +101,7 @@ public void changed(ObservableValue observable, } }); - targetPathInput.setText(AppVaribles.getUserConfigValue(targetPathKey, CommonValues.UserFilePath)); + targetPathInput.setText(AppVaribles.getUserConfigPath(targetPathKey).getAbsolutePath()); targetPathInput.textProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue observable, @@ -150,8 +149,10 @@ public void changed(ObservableValue ov, protected void selectSourcePath(ActionEvent event) { try { DirectoryChooser chooser = new DirectoryChooser(); - File path = new File(AppVaribles.getUserConfigPath(sourcePathKey, CommonValues.UserFilePath)); - chooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(sourcePathKey); + if (path != null) { + chooser.setInitialDirectory(path); + } File directory = chooser.showDialog(getMyStage()); if (directory == null) { return; @@ -173,8 +174,10 @@ protected void selectTargetPath(ActionEvent event) { } try { DirectoryChooser chooser = new DirectoryChooser(); - File path = new File(AppVaribles.getUserConfigPath(targetPathKey, CommonValues.UserFilePath)); - chooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(targetPathKey); + if (path != null) { + chooser.setInitialDirectory(path); + } File directory = chooser.showDialog(getMyStage()); if (directory == null) { return; @@ -295,7 +298,7 @@ protected boolean initAttributes() { @FXML @Override - protected void startProcess(ActionEvent event) { + public void startAction() { try { if (!initAttributes()) { return; @@ -408,7 +411,7 @@ public void handle(ActionEvent event) { operationBarController.pauseButton.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { - startProcess(event); + startAction(); } }); } else { @@ -416,7 +419,7 @@ public void handle(ActionEvent event) { operationBarController.startButton.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { - startProcess(event); + startAction(); } }); operationBarController.pauseButton.setVisible(false); diff --git a/MyBox/src/main/java/mara/mybox/controller/FileCutController.java b/MyBox/src/main/java/mara/mybox/controller/FileCutController.java index 9cbc066fd..336928e28 100644 --- a/MyBox/src/main/java/mara/mybox/controller/FileCutController.java +++ b/MyBox/src/main/java/mara/mybox/controller/FileCutController.java @@ -16,10 +16,10 @@ import javafx.scene.text.Font; import mara.mybox.fxml.FxmlTools; import static mara.mybox.fxml.FxmlTools.badStyle; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.FileInformation; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.value.CommonValues; +import mara.mybox.data.FileInformation; import mara.mybox.tools.ByteTools; import mara.mybox.tools.FileTools; @@ -186,7 +186,7 @@ public void changed(ObservableValue observable, String oldValu } } }); - targetPathInput.setText(AppVaribles.getUserConfigValue(targetPathKey, CommonValues.UserFilePath)); + targetPathInput.setText(AppVaribles.getUserConfigPath(targetPathKey).getAbsolutePath()); operationBarController.openTargetButton.disableProperty().bind(Bindings.isEmpty(targetPathInput.textProperty()) .or(targetPathInput.styleProperty().isEqualTo(badStyle)) diff --git a/MyBox/src/main/java/mara/mybox/controller/FileEditerController.java b/MyBox/src/main/java/mara/mybox/controller/FileEditerController.java index 0b22a229f..e517aa018 100644 --- a/MyBox/src/main/java/mara/mybox/controller/FileEditerController.java +++ b/MyBox/src/main/java/mara/mybox/controller/FileEditerController.java @@ -33,19 +33,20 @@ import javafx.scene.layout.AnchorPane; import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; +import javafx.scene.layout.Region; import javafx.scene.layout.VBox; import javafx.scene.text.Font; import javafx.stage.FileChooser; import javafx.stage.Modality; import mara.mybox.fxml.FxmlTools; import static mara.mybox.fxml.FxmlTools.badStyle; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.FileEditInformation; -import mara.mybox.objects.FileEditInformation.Edit_Type; -import mara.mybox.objects.FileEditInformation.Filter_Type; -import mara.mybox.objects.FileEditInformation.Line_Break; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.CommonValues; +import mara.mybox.data.FileEditInformation; +import mara.mybox.data.FileEditInformation.Edit_Type; +import mara.mybox.data.FileEditInformation.Filter_Type; +import mara.mybox.data.FileEditInformation.Line_Break; import mara.mybox.tools.StringTools; import mara.mybox.tools.TextTools; @@ -63,7 +64,7 @@ public abstract class FileEditerController extends BaseController { protected int currentFound, currentPageTmp, lineLocation, objectLocation; protected long pageSize, currentPage; protected SimpleBooleanProperty fileChanged; - protected boolean isSettingValues, findWhole, charsetByUser; + protected boolean findWhole, charsetByUser; protected FileEditInformation sourceInformation, targetInformation; protected SaveAsType saveAsType; protected TextArea displayArea; @@ -98,12 +99,11 @@ public enum SaveAsType { @FXML protected Label editLabel, bomLabel, pageLabel, charsetLabel, selectionLabel; @FXML - protected Button openButton, createButton, saveButton, charactersButton, linesButton, recoverButton, - redoButton, undoButton, deleteButton, cutButton, copyButton, pasteButton, selectAllButton, + protected Button openButton, createButton, charactersButton, linesButton, recoverButton, + redoButton, undoButton, cutButton, pasteButton, findFirstButton, findPreviousButton, findNextButton, findLastButton, countButton, - replaceButton, replaceAllButton, filterButton, infoButton, pageSizeButton, - firstPageButton, perviousPageButton, nextPageButton, lastPageButton, pageGoButton, - locateObjectButton, locateLineButton; + replaceButton, replaceAllButton, filterButton, + pageGoButton, locateObjectButton, locateLineButton; @FXML protected TextField fromInput, toInput, pageSizeInput, pageInput, filterInput, findInput, replaceInput, currentLineBreak, objectNumberInput, lineInput; @@ -335,11 +335,8 @@ protected void checkSaveAsType() { protected void initEditBar() { try { - Tooltip tips = new Tooltip("CTRL+c"); - tips.setFont(new Font(16)); - FxmlTools.quickTooltip(copyButton, tips); - tips = new Tooltip("CTRL+v"); + Tooltip tips = new Tooltip("CTRL+v"); tips.setFont(new Font(16)); FxmlTools.quickTooltip(pasteButton, tips); @@ -351,21 +348,13 @@ protected void initEditBar() { tips.setFont(new Font(16)); FxmlTools.quickTooltip(undoButton, tips); - tips = new Tooltip("CTRL+a"); - tips.setFont(new Font(16)); - FxmlTools.quickTooltip(selectAllButton, tips); - tips = new Tooltip("CTRL+x"); tips.setFont(new Font(16)); FxmlTools.quickTooltip(cutButton, tips); - tips = new Tooltip("CTRL+d"); - tips.setFont(new Font(16)); - FxmlTools.quickTooltip(deleteButton, tips); - - tips = new Tooltip("CTRL+s"); + tips = new Tooltip("CTRL+r"); tips.setFont(new Font(16)); - FxmlTools.quickTooltip(saveButton, tips); + FxmlTools.quickTooltip(recoverButton, tips); } catch (Exception e) { logger.error(e.toString()); @@ -572,6 +561,10 @@ protected void initReplaceTab() { tips.setFont(new Font(16)); FxmlTools.quickTooltip(findFirstButton, tips); + tips = new Tooltip("CTRL+l"); + tips.setFont(new Font(16)); + FxmlTools.quickTooltip(findLastButton, tips); + tips = new Tooltip("CTRL+n"); tips.setFont(new Font(16)); FxmlTools.quickTooltip(findNextButton, tips); @@ -580,7 +573,7 @@ protected void initReplaceTab() { tips.setFont(new Font(16)); FxmlTools.quickTooltip(findPreviousButton, tips); - tips = new Tooltip("CTRL+r"); + tips = new Tooltip("CTRL+e"); tips.setFont(new Font(16)); FxmlTools.quickTooltip(replaceButton, tips); @@ -869,7 +862,11 @@ protected void setSecondAreaSelection() { } @FXML - protected void copyAction() { + @Override + public void copyAction() { + if (!mainArea.isFocused()) { + return; + } try { if (!copyButton.isDisabled()) { mainArea.copy(); @@ -881,6 +878,9 @@ protected void copyAction() { @FXML protected void pasteAction() { + if (!mainArea.isFocused()) { + return; + } try { if (!pasteButton.isDisabled()) { mainArea.paste(); @@ -892,6 +892,9 @@ protected void pasteAction() { @FXML protected void cutAction() { + if (!mainArea.isFocused()) { + return; + } try { if (!cutButton.isDisabled()) { mainArea.cut(); @@ -902,7 +905,11 @@ protected void cutAction() { } @FXML - protected void deleteAction() { + @Override + public void deleteAction() { + if (!mainArea.isFocused()) { + return; + } try { if (!deleteButton.isDisabled()) { mainArea.deleteText(mainArea.getSelection()); @@ -913,7 +920,11 @@ protected void deleteAction() { } @FXML - protected void selectAllAction() { + @Override + public void selectAllAction() { + if (!mainArea.isFocused()) { + return; + } try { if (!selectAllButton.isDisabled()) { mainArea.selectAll(); @@ -925,6 +936,9 @@ protected void selectAllAction() { @FXML protected void redoAction() { + if (!mainArea.isFocused()) { + return; + } try { if (!redoButton.isDisabled()) { mainArea.redo(); @@ -936,6 +950,9 @@ protected void redoAction() { @FXML protected void undoAction() { + if (!mainArea.isFocused()) { + return; + } try { if (!undoButton.isDisabled()) { mainArea.undo(); @@ -947,6 +964,9 @@ protected void undoAction() { @FXML protected void recoverAction() { + if (!mainArea.isFocused()) { + return; + } try { if (!recoverButton.isDisabled() && sourceInformation.getFile() != null) { loadPage(); @@ -959,58 +979,41 @@ protected void recoverAction() { @Override protected void keyEventsHandler(KeyEvent event) { super.keyEventsHandler(event); - String key = event.getText(); - if (key == null || key.isEmpty()) { - return; - } if (event.isControlDown()) { + String key = event.getText(); + if (key == null || key.isEmpty()) { + return; + } switch (key) { - case "c": - case "C": - if (mainArea.isFocused() && !copyButton.isDisabled()) { - copyAction(); - } - break; - case "v": - case "V": - if (mainArea.isFocused() && !pasteButton.isDisabled()) { - pasteAction(); - } - break; - case "z": - case "Z": - if (mainArea.isFocused() && !undoButton.isDisabled()) { - undoAction(); - } - break; - case "y": - case "Y": - if (mainArea.isFocused() && !redoButton.isDisabled()) { - redoAction(); - } - break; - case "a": - case "A": - if (mainArea.isFocused() && !selectAllButton.isDisabled()) { - selectAllAction(); - } - break; - case "x": - case "X": - if (mainArea.isFocused() && !cutButton.isDisabled()) { - cutAction(); - } - break; - case "d": - case "D": - if (mainArea.isFocused() && !deleteButton.isDisabled()) { - deleteAction(); - } - break; - case "s": - case "S": - if (!saveButton.isDisabled()) { - saveAction(); + // TextArea itself supports these shortcuts. +// case "v": +// case "V": +// if (mainArea.isFocused() && !pasteButton.isDisabled()) { +// pasteAction(); +// } +// break; +// case "z": +// case "Z": +// if (mainArea.isFocused() && !undoButton.isDisabled()) { +// undoAction(); +// } +// break; +// case "y": +// case "Y": +// if (mainArea.isFocused() && !redoButton.isDisabled()) { +// redoAction(); +// } +// break; +// case "x": +// case "X": +// if (mainArea.isFocused() && !cutButton.isDisabled()) { +// cutAction(); +// } +// break; + case "r": + case "R": + if (mainArea.isFocused() && !recoverButton.isDisabled()) { + recoverAction(); } break; case "f": @@ -1019,6 +1022,12 @@ protected void keyEventsHandler(KeyEvent event) { findFirstAction(); } break; + case "l": + case "L": + if (!findLastButton.isDisabled()) { + findLastAction(); + } + break; case "n": case "N": if (!findNextButton.isDisabled()) { @@ -1031,8 +1040,8 @@ protected void keyEventsHandler(KeyEvent event) { findPreviousAction(); } break; - case "r": - case "R": + case "e": + case "E": if (!replaceButton.isDisabled()) { replaceAction(); } @@ -1044,7 +1053,8 @@ protected void keyEventsHandler(KeyEvent event) { } @FXML - protected void pageSizeAction() { + @Override + public void okAction() { if (!checkSavingForNextAction()) { return; } @@ -1469,6 +1479,7 @@ protected void replaceAllAction() { Alert alert = new Alert(Alert.AlertType.CONFIRMATION); alert.setTitle(getMyStage().getTitle()); alert.setContentText(AppVaribles.getMessage("SureReplaceAll")); + alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); ButtonType buttonSure = new ButtonType(AppVaribles.getMessage("Sure")); ButtonType buttonCancel = new ButtonType(AppVaribles.getMessage("Cancel")); alert.getButtonTypes().setAll(buttonSure, buttonCancel); @@ -1558,12 +1569,13 @@ protected void filterAction() { } @FXML - protected void nextPageAction() { + @Override + public void nextAction() { if (!checkSavingForNextAction()) { return; } if (sourceInformation.getObjectsNumber() <= sourceInformation.getCurrentPageObjectEnd()) { - nextPageButton.setDisable(true); + nextButton.setDisable(true); } else { sourceInformation.setCurrentPage(sourceInformation.getCurrentPage() + 1); currentFound = -1; @@ -1572,12 +1584,13 @@ protected void nextPageAction() { } @FXML - protected void previousPageAction() { + @Override + public void previousAction() { if (!checkSavingForNextAction()) { return; } if (sourceInformation.getCurrentPage() <= 1) { - perviousPageButton.setDisable(true); + previousButton.setDisable(true); } else { sourceInformation.setCurrentPage(sourceInformation.getCurrentPage() - 1); currentFound = -1; @@ -1586,7 +1599,8 @@ protected void previousPageAction() { } @FXML - protected void firstPageAction() { + @Override + public void firstAction() { if (!checkSavingForNextAction()) { return; } @@ -1596,7 +1610,8 @@ protected void firstPageAction() { } @FXML - protected void lastPageAction() { + @Override + public void lastAction() { if (!checkSavingForNextAction()) { return; } @@ -1619,7 +1634,8 @@ protected void goPageAction() { } @FXML - protected void infoAction() { + @Override + public void infoAction() { } @@ -1756,8 +1772,10 @@ protected void openAction() { } final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(FilePathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(FilePathKey); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } fileChooser.getExtensionFilters().addAll(fileExtensionFilter); final File file = fileChooser.showOpenDialog(getMyStage()); if (file == null) { @@ -1973,13 +1991,14 @@ protected void updateInterface(boolean changed) { } else { getMyStage().setTitle(t); } - if (editLabel != null) { - editLabel.setText(""); - } if (!formatMainArea()) { - editLabel.setText(AppVaribles.getMessage("InvalidData")); + if (editLabel != null) { + editLabel.setText(AppVaribles.getMessage("InvalidData")); + } mainArea.setStyle(badStyle); return; + } else if (editLabel != null) { + editLabel.setText(""); } mainArea.setStyle(null); String text = mainArea.getText(); @@ -2038,15 +2057,12 @@ protected void updateInterface(boolean changed) { if (currentBox != null) { currentBox.setDisable(changed || sourceInformation.isWithBom()); } - if (editLabel != null && changed) { - editLabel.setText(AppVaribles.getMessage("PaginateComments")); - } if (locateObjectButton != null) { locateObjectButton.setDisable(changed); locateLineButton.setDisable(changed); } - perviousPageButton.setDisable(sourceInformation.getCurrentPage() <= 1); - nextPageButton.setDisable(sourceInformation.getObjectsNumber() <= sourceInformation.getCurrentPageObjectEnd()); + previousButton.setDisable(sourceInformation.getCurrentPage() <= 1); + nextButton.setDisable(sourceInformation.getObjectsNumber() <= sourceInformation.getCurrentPageObjectEnd()); if (sourceInformation.getObjectsNumber() % sourceInformation.getPageSize() == 0) { sourceInformation.setPagesNumber(sourceInformation.getObjectsNumber() / sourceInformation.getPageSize()); } else { @@ -2084,8 +2100,8 @@ protected void updateInterface(boolean changed) { } } } - if (pageSizeButton != null) { - pageSizeButton.setDisable(changed); + if (okButton != null) { + okButton.setDisable(changed); } setSecondArea(text); @@ -2138,7 +2154,8 @@ protected void countCurrentFound() { } @FXML - protected void saveAction() { + @Override + public void saveAction() { if (sourceFile == null) { saveNew(); } else { @@ -2148,8 +2165,10 @@ protected void saveAction() { protected void saveNew() { final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(FilePathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(FilePathKey); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } fileChooser.getExtensionFilters().addAll(fileExtensionFilter); final File file = fileChooser.showSaveDialog(getMyStage()); if (file == null) { @@ -2196,6 +2215,7 @@ protected void saveExisted() { Alert alert = new Alert(Alert.AlertType.CONFIRMATION); alert.setTitle(getMyStage().getTitle()); alert.setContentText(AppVaribles.getMessage("SureOverrideFile")); + alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); ButtonType buttonSave = new ButtonType(AppVaribles.getMessage("Save")); ButtonType buttonSaveAs = new ButtonType(AppVaribles.getMessage("SaveAs")); ButtonType buttonCancel = new ButtonType(AppVaribles.getMessage("Cancel")); @@ -2247,8 +2267,10 @@ public void run() { @FXML protected void saveAsAction() { final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(FilePathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(FilePathKey); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } fileChooser.getExtensionFilters().addAll(fileExtensionFilter); final File file = fileChooser.showSaveDialog(getMyStage()); if (file == null) { @@ -2352,6 +2374,7 @@ public boolean checkSavingForNextAction() { Alert alert = new Alert(Alert.AlertType.CONFIRMATION); alert.setTitle(getMyStage().getTitle()); alert.setContentText(AppVaribles.getMessage("NeedSaveBeforeAction")); + alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); ButtonType buttonSave = new ButtonType(AppVaribles.getMessage("Save")); ButtonType buttonNotSave = new ButtonType(AppVaribles.getMessage("NotSave")); ButtonType buttonCancel = new ButtonType(AppVaribles.getMessage("Cancel")); diff --git a/MyBox/src/main/java/mara/mybox/controller/FileFilterController.java b/MyBox/src/main/java/mara/mybox/controller/FileFilterController.java index 9141ce73f..326cb29aa 100644 --- a/MyBox/src/main/java/mara/mybox/controller/FileFilterController.java +++ b/MyBox/src/main/java/mara/mybox/controller/FileFilterController.java @@ -8,10 +8,9 @@ import javafx.scene.control.TextField; import javafx.stage.FileChooser; import javafx.stage.Modality; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.FileEditInformation; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.data.FileEditInformation; /** * @Author Mara @@ -101,10 +100,12 @@ public void run() { @FXML @Override - protected void saveAction() { + public void saveAction() { final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(FilePathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(FilePathKey); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } fileChooser.getExtensionFilters().addAll(fileExtensionFilter); final File file = fileChooser.showSaveDialog(getMyStage()); if (file == null) { diff --git a/MyBox/src/main/java/mara/mybox/controller/FileMergeController.java b/MyBox/src/main/java/mara/mybox/controller/FileMergeController.java index e6cc43a28..37eb3050b 100644 --- a/MyBox/src/main/java/mara/mybox/controller/FileMergeController.java +++ b/MyBox/src/main/java/mara/mybox/controller/FileMergeController.java @@ -1,5 +1,6 @@ package mara.mybox.controller; +import mara.mybox.fxml.FxmlStage; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -13,10 +14,10 @@ import javafx.fxml.FXML; import javafx.stage.FileChooser; import static mara.mybox.fxml.FxmlTools.badStyle; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.FileInformation; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.CommonValues; +import mara.mybox.data.FileInformation; import mara.mybox.tools.ByteTools; /** @@ -61,8 +62,8 @@ public void changed(ObservableValue observable, String oldValu protected void selectTargetFile(ActionEvent event) { try { final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(targetPathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(targetPathKey); + if ( path.exists() ) fileChooser.setInitialDirectory(path); fileChooser.getExtensionFilters().addAll(CommonValues.PdfExtensionFilter); final File file = fileChooser.showSaveDialog(getMyStage()); if (file == null) { @@ -172,13 +173,13 @@ protected void viewFile(File file) { AppVaribles.getMessage("BytesEditer"), false, true); controller.openFile(file); } else { - OpenFile.openTarget(getClass(), null, file.getAbsolutePath()); + FxmlStage.openTarget(getClass(), null, file.getAbsolutePath()); } } @Override protected void openTarget(ActionEvent event) { - OpenFile.openTarget(getClass(), null, targetFile.getAbsolutePath()); + FxmlStage.openTarget(getClass(), null, targetFile.getAbsolutePath()); } } diff --git a/MyBox/src/main/java/mara/mybox/controller/FilesArrangeController.java b/MyBox/src/main/java/mara/mybox/controller/FilesArrangeController.java index 957232b7e..eec632234 100644 --- a/MyBox/src/main/java/mara/mybox/controller/FilesArrangeController.java +++ b/MyBox/src/main/java/mara/mybox/controller/FilesArrangeController.java @@ -27,14 +27,13 @@ import javafx.stage.DirectoryChooser; import javafx.stage.FileChooser; import mara.mybox.fxml.FxmlTools; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.FileSynchronizeAttributes; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.data.FileSynchronizeAttributes; import mara.mybox.tools.DateTools; import mara.mybox.tools.FileTools; import static mara.mybox.fxml.FxmlTools.badStyle; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.logger; import mara.mybox.tools.ValueTools; /** @@ -126,7 +125,7 @@ protected void initializeNext() { } private void initDirTab() { - sourcePathInput.setText(AppVaribles.getUserConfigValue(sourcePathKey, CommonValues.UserFilePath)); + sourcePathInput.setText(AppVaribles.getUserConfigPath(sourcePathKey).getAbsolutePath()); sourcePathInput.textProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue observable, @@ -142,7 +141,7 @@ public void changed(ObservableValue observable, } }); - targetPathInput.setText(AppVaribles.getUserConfigValue(targetPathKey, CommonValues.UserFilePath)); + targetPathInput.setText(AppVaribles.getUserConfigPath(targetPathKey).getAbsolutePath()); targetPathInput.textProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue observable, @@ -294,8 +293,10 @@ private void checkDirType() { protected void selectSourcePath(ActionEvent event) { try { DirectoryChooser chooser = new DirectoryChooser(); - File path = new File(AppVaribles.getUserConfigPath(sourcePathKey, CommonValues.UserFilePath)); - chooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(sourcePathKey); + if (path != null) { + chooser.setInitialDirectory(path); + } File directory = chooser.showDialog(getMyStage()); if (directory == null) { return; @@ -314,8 +315,10 @@ protected void selectTargetPath(ActionEvent event) { } try { DirectoryChooser chooser = new DirectoryChooser(); - File path = new File(AppVaribles.getUserConfigPath(targetPathKey, CommonValues.UserFilePath)); - chooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(targetPathKey); + if (path != null) { + chooser.setInitialDirectory(path); + } File directory = chooser.showDialog(getMyStage()); if (directory == null) { return; @@ -389,7 +392,7 @@ protected boolean initAttributes() { @FXML @Override - protected void startProcess(ActionEvent event) { + public void startAction() { try { if (!initAttributes()) { return; @@ -488,7 +491,7 @@ public void handle(ActionEvent event) { operationBarController.pauseButton.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { - startProcess(event); + startAction(); } }); @@ -497,7 +500,7 @@ public void handle(ActionEvent event) { operationBarController.startButton.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { - startProcess(event); + startAction(); } }); operationBarController.pauseButton.setVisible(false); diff --git a/MyBox/src/main/java/mara/mybox/controller/FilesBatchController.java b/MyBox/src/main/java/mara/mybox/controller/FilesBatchController.java index 60d6800b6..7a45cb08b 100644 --- a/MyBox/src/main/java/mara/mybox/controller/FilesBatchController.java +++ b/MyBox/src/main/java/mara/mybox/controller/FilesBatchController.java @@ -33,13 +33,13 @@ import javafx.stage.DirectoryChooser; import javafx.stage.FileChooser; import javafx.util.Callback; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.FileInformation; +import mara.mybox.value.AppVaribles; +import mara.mybox.value.CommonValues; +import mara.mybox.data.FileInformation; import mara.mybox.fxml.FxmlTools; import static mara.mybox.fxml.FxmlTools.badStyle; -import static mara.mybox.objects.AppVaribles.getMessage; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.getMessage; +import static mara.mybox.value.AppVaribles.logger; import mara.mybox.tools.DateTools; import mara.mybox.tools.ValueTools; @@ -81,7 +81,7 @@ protected class ProcessParameters { protected TextField targetSuffixInput; @FXML protected Button addFilesButton, addDirectoryButton, insertFilesButton, insertDirectoryButton, - upButton, downButton, deleteButton, clearButton, openButton; + upButton, downButton, clearButton, openButton; @FXML protected CheckBox subDirCheck, filesNameCheck; @FXML @@ -249,7 +249,7 @@ public void changed(ObservableValue observable, String oldValu } } }); - targetPathInput.setText(AppVaribles.getUserConfigValue(targetPathKey, CommonValues.UserFilePath)); + targetPathInput.setText(AppVaribles.getUserConfigPath(targetPathKey).getAbsolutePath()); targetExistGroup.selectedToggleProperty().addListener(new ChangeListener() { @Override @@ -333,8 +333,10 @@ protected void insertDirectoryAction(ActionEvent event) { protected void addFilesAction(int index) { try { final FileChooser fileChooser = new FileChooser(); - File defaultPath = new File(AppVaribles.getUserConfigPath(sourcePathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(defaultPath); + File defaultPath = AppVaribles.getUserConfigPath(sourcePathKey); + if (defaultPath.exists()) { + fileChooser.setInitialDirectory(defaultPath); + } fileChooser.getExtensionFilters().addAll(fileExtensionFilter); List files = fileChooser.showOpenMultipleDialog(getMyStage()); @@ -368,8 +370,10 @@ protected void addFilesAction(int index) { protected void addDirectoryAction(int index) { try { DirectoryChooser dirChooser = new DirectoryChooser(); - File defaultPath = new File(AppVaribles.getUserConfigPath(sourcePathKey, CommonValues.UserFilePath)); - dirChooser.setInitialDirectory(defaultPath); + File defaultPath = AppVaribles.getUserConfigPath(sourcePathKey); + if (defaultPath != null) { + dirChooser.setInitialDirectory(defaultPath); + } File directory = dirChooser.showDialog(getMyStage()); if (directory == null) { return; @@ -392,7 +396,8 @@ protected void addDirectoryAction(int index) { } @FXML - protected void deleteAction(ActionEvent event) { + @Override + public void deleteAction() { List selected = new ArrayList<>(); selected.addAll(sourceTableView.getSelectionModel().getSelectedIndices()); if (selected.isEmpty()) { @@ -493,7 +498,7 @@ protected void openTarget(ActionEvent event) { @FXML @Override - protected void startProcess(ActionEvent event) { + public void startAction() { isPreview = false; makeActualParameters(); currentParameters = actualParameters; @@ -755,7 +760,7 @@ public void handle(ActionEvent event) { operationBarController.pauseButton.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { - startProcess(event); + startAction(); } }); paraBox.setDisable(true); @@ -764,7 +769,7 @@ public void handle(ActionEvent event) { operationBarController.startButton.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { - startProcess(event); + startAction(); } }); operationBarController.pauseButton.setVisible(false); diff --git a/MyBox/src/main/java/mara/mybox/controller/FilesRenameController.java b/MyBox/src/main/java/mara/mybox/controller/FilesRenameController.java index ca2019d8e..8c7ec63e5 100644 --- a/MyBox/src/main/java/mara/mybox/controller/FilesRenameController.java +++ b/MyBox/src/main/java/mara/mybox/controller/FilesRenameController.java @@ -24,10 +24,10 @@ import javafx.scene.control.ToggleGroup; import javafx.scene.control.cell.PropertyValueFactory; import javafx.stage.FileChooser; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.FileInformation; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.getMessage; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.data.FileInformation; import mara.mybox.tools.FileTools; import mara.mybox.tools.FileTools.FileSortType; @@ -352,7 +352,7 @@ protected String makeFilename(File file) { if (accumCheck.isSelected()) { String pageNumber = currentAccum + ""; if (fillZero.isSelected()) { - pageNumber = ValueTools.fillNumber(currentAccum, digit); + pageNumber = ValueTools.fillLeftZero(currentAccum, digit); } filename += pageNumber; currentAccum++; diff --git a/MyBox/src/main/java/mara/mybox/controller/FilesTableController.java b/MyBox/src/main/java/mara/mybox/controller/FilesTableController.java index cfdab7bef..01ac01f44 100644 --- a/MyBox/src/main/java/mara/mybox/controller/FilesTableController.java +++ b/MyBox/src/main/java/mara/mybox/controller/FilesTableController.java @@ -16,10 +16,9 @@ import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.layout.Pane; import javafx.stage.FileChooser; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.FileInformation; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.data.FileInformation; /** * @Author Mara @@ -34,7 +33,7 @@ public class FilesTableController extends BaseController { @FXML protected Pane filesTablePane; @FXML - protected Button addButton, clearButton, deleteButton, upButton, downButton, insertButton; + protected Button addButton, clearButton, upButton, downButton, insertButton; @FXML protected Button recoveryAllButton, recoverySelectedButton; @FXML @@ -100,8 +99,10 @@ void insertAction(ActionEvent event) { void addAction(int index) { try { final FileChooser fileChooser = new FileChooser(); - File defaultPath = new File(AppVaribles.getUserConfigPath(parentController.sourcePathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(defaultPath); + File defaultPath = AppVaribles.getUserConfigPath(parentController.sourcePathKey); + if (defaultPath.exists()) { + fileChooser.setInitialDirectory(defaultPath); + } fileChooser.getExtensionFilters().addAll(parentController.fileExtensionFilter); List files = fileChooser.showOpenMultipleDialog(getMyStage()); if (files == null || files.isEmpty()) { @@ -199,7 +200,8 @@ void clearAction(ActionEvent event) { } @FXML - void deleteAction(ActionEvent event) { + @Override + public void deleteAction() { List selected = new ArrayList<>(); selected.addAll(filesTableView.getSelectionModel().getSelectedIndices()); if (selected.isEmpty()) { diff --git a/MyBox/src/main/java/mara/mybox/controller/HtmlEditorController.java b/MyBox/src/main/java/mara/mybox/controller/HtmlEditorController.java index fe1c871b0..1f05ad44f 100644 --- a/MyBox/src/main/java/mara/mybox/controller/HtmlEditorController.java +++ b/MyBox/src/main/java/mara/mybox/controller/HtmlEditorController.java @@ -1,5 +1,6 @@ package mara.mybox.controller; +import mara.mybox.fxml.FxmlStage; import java.awt.image.BufferedImage; import java.io.BufferedWriter; import java.io.File; @@ -46,6 +47,7 @@ import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.scene.layout.Pane; +import javafx.scene.layout.Region; import javafx.scene.paint.Color; import javafx.scene.text.Font; import javafx.scene.web.HTMLEditor; @@ -64,15 +66,15 @@ import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.logger; import mara.mybox.db.TableBrowserUrls; -import mara.mybox.imagefile.ImageFileWriters; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.CommonValues; +import mara.mybox.image.file.ImageFileWriters; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.value.CommonValues; import mara.mybox.tools.FileTools; import static mara.mybox.fxml.FxmlTools.badStyle; -import mara.mybox.fxml.FxmlImageTools; +import mara.mybox.fxml.image.ImageTools; import mara.mybox.fxml.FxmlTools; import mara.mybox.tools.NetworkTools; import static mara.mybox.tools.NetworkTools.checkWeiboPassport; @@ -99,7 +101,7 @@ public class HtmlEditorController extends BaseController { private Stage snapingStage; private LoadingController loadingController; private float zoomScale; - protected boolean isSettingValues, loadSynchronously, isFrameSet; + protected boolean loadSynchronously, isFrameSet; protected SimpleBooleanProperty fileChanged; protected int cols, rows; protected int lastTextLen; @@ -560,8 +562,10 @@ protected void openAction() { } final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(HtmlFilePathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(HtmlFilePathKey); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } fileChooser.getExtensionFilters().addAll(fileExtensionFilter); final File file = fileChooser.showOpenDialog(getMyStage()); if (file == null) { @@ -637,13 +641,16 @@ private String getBrowserContents() { } @FXML - protected void saveAction() { + @Override + public void saveAction() { try { isSettingValues = true; if (sourceFile == null) { final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(HtmlFilePathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(HtmlFilePathKey); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } fileChooser.getExtensionFilters().addAll(fileExtensionFilter); final File file = fileChooser.showSaveDialog(getMyStage()); if (file == null) { @@ -678,8 +685,10 @@ protected void saveAsAction() { try { isSettingValues = true; final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(HtmlFilePathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(HtmlFilePathKey); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } fileChooser.getExtensionFilters().addAll(fileExtensionFilter); final File file = fileChooser.showSaveDialog(getMyStage()); if (file == null) { @@ -730,13 +739,15 @@ private void snapshot(ActionEvent event) { final FileChooser fileChooser = new FileChooser(); File path; if (isOneImage) { - path = new File(AppVaribles.getUserConfigPath(HtmlImagePathKey, CommonValues.UserFilePath)); + path = AppVaribles.getUserConfigPath(HtmlImagePathKey); fileChooser.getExtensionFilters().addAll(CommonValues.ImageExtensionFilter); } else { - path = new File(AppVaribles.getUserConfigPath(HtmlPdfPathKey, CommonValues.UserFilePath)); + path = AppVaribles.getUserConfigPath(HtmlPdfPathKey); fileChooser.getExtensionFilters().addAll(CommonValues.PdfExtensionFilter); } - fileChooser.setInitialDirectory(path); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } final File file = fileChooser.showSaveDialog(getMyStage()); if (file == null) { return; @@ -870,10 +881,10 @@ public void run() { Image snapshot = webView.snapshot(parameters, null); if (totalHeight < snapHeight + snapStep) { // last snap - snapshot = FxmlImageTools.cropImage(snapshot, 0, snapStep - (totalHeight - snapHeight), + snapshot = ImageTools.cropImage(snapshot, 0, snapStep - (totalHeight - snapHeight), width - 1, (int) snapshot.getHeight() - 1); } else { - snapshot = FxmlImageTools.cropImage(snapshot, 0, 0, + snapshot = ImageTools.cropImage(snapshot, 0, 0, width - 1, (int) snapshot.getHeight() - 1); } images.add(snapshot); @@ -884,10 +895,10 @@ public void run() { loadingController.setInfo(AppVaribles.getMessage("WritingFile")); boolean success = true; if (isOneImage) { - Image finalImage = FxmlImageTools.combineSingleColumn(images); + Image finalImage = ImageTools.combineSingleColumn(images); if (finalImage != null) { String format = FileTools.getFileSuffix(targetFile.getAbsolutePath()); - final BufferedImage bufferedImage = FxmlImageTools.getBufferedImage(finalImage); + final BufferedImage bufferedImage = ImageTools.getBufferedImage(finalImage); ImageFileWriters.writeImageFile(bufferedImage, format, targetFile.getAbsolutePath()); } else { success = false; @@ -896,7 +907,7 @@ public void run() { success = PdfTools.htmlIntoPdf(images, targetFile, windowSizeCheck.isSelected()); } if (success && targetFile.exists()) { - OpenFile.openTarget(getClass(), null, targetFile.getAbsolutePath()); + FxmlStage.openTarget(getClass(), null, targetFile.getAbsolutePath()); } else { popError(AppVaribles.getMessage("Failed")); } @@ -991,7 +1002,6 @@ public boolean stageReloading() { @Override public boolean stageClosing() { - super.stageClosing(); Platform.runLater(new Runnable() { @Override public void run() { @@ -1009,7 +1019,8 @@ public void run() { timer.cancel(); } loadingController = null; - return true; + return super.stageClosing(); + } public boolean checkSavingForNextAction() { @@ -1021,6 +1032,7 @@ public boolean checkSavingForNextAction() { Alert alert = new Alert(Alert.AlertType.CONFIRMATION); alert.setTitle(getMyStage().getTitle()); alert.setContentText(AppVaribles.getMessage("FileChanged")); + alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); ButtonType buttonSave = new ButtonType(AppVaribles.getMessage("Save")); ButtonType buttonNotSave = new ButtonType(AppVaribles.getMessage("NotSave")); ButtonType buttonCancel = new ButtonType(AppVaribles.getMessage("Cancel")); diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageAttributesBaseController.java b/MyBox/src/main/java/mara/mybox/controller/ImageAttributesBaseController.java index 20443537f..313401179 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageAttributesBaseController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageAttributesBaseController.java @@ -3,18 +3,19 @@ import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.fxml.FXML; +import javafx.scene.control.CheckBox; import javafx.scene.control.RadioButton; import javafx.scene.control.TextField; import javafx.scene.control.Toggle; import javafx.scene.control.ToggleGroup; import javafx.scene.control.Tooltip; import javafx.scene.layout.HBox; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.ImageAttributes; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.data.ImageAttributes; import mara.mybox.fxml.FxmlTools; -import mara.mybox.image.ImageValueTools; +import mara.mybox.image.ImageValue; import org.apache.pdfbox.rendering.ImageType; /** @@ -39,6 +40,8 @@ public class ImageAttributesBaseController extends BaseController { protected HBox qualityBox, compressBox, colorBox; @FXML protected RadioButton rawSelect, pcxSelect; + @FXML + protected CheckBox ditherCheck; protected ImageAttributes attributes = new ImageAttributes(); @@ -109,7 +112,7 @@ public void changed(ObservableValue ov, checkColorConversion(); } }); - FxmlTools.setRadioSelected(binaryGroup, AppVaribles.getUserConfigValue(ImageBinaryKey, AppVaribles.getMessage("Default"))); + FxmlTools.setRadioSelected(binaryGroup, AppVaribles.getUserConfigValue(ImageBinaryKey, AppVaribles.getMessage("OTSU"))); thresholdInput.textProperty().addListener(new ChangeListener() { @Override @@ -120,6 +123,15 @@ public void changed(ObservableValue observable, }); thresholdInput.setText(AppVaribles.getUserConfigValue(ImageBinaryInputKey, null)); + ditherCheck.selectedProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue ov, Boolean oldValue, Boolean newValue) { + attributes.setIsDithering(newValue); + } + }); + attributes.setIsDithering(ditherCheck.isSelected()); + FxmlTools.setComments(ditherCheck, new Tooltip(getMessage("DitherComments"))); + if (pcxSelect != null) { FxmlTools.quickTooltip(pcxSelect, new Tooltip(getMessage("PcxComments"))); } @@ -138,7 +150,7 @@ protected void checkImageFormat() { attributes.setImageFormat(imageFormat); AppVaribles.setUserConfigValue(ImageFormatKey, imageFormat); - String[] compressionTypes = ImageValueTools.getCompressionTypes(imageFormat, attributes.getColorSpace()); + String[] compressionTypes = ImageValue.getCompressionTypes(imageFormat, attributes.getColorSpace()); checkCompressionTypes(compressionTypes); if (compressionTypes != null && "jpg".equals(imageFormat)) { @@ -203,7 +215,7 @@ protected void checkImageColor() { } // if ("tif".equals(imageFormat) || "bmp".equals(imageFormat)) { - String[] compressionTypes = ImageValueTools.getCompressionTypes(attributes.getImageFormat(), attributes.getColorSpace()); + String[] compressionTypes = ImageValue.getCompressionTypes(attributes.getImageFormat(), attributes.getColorSpace()); checkCompressionTypes(compressionTypes); // } @@ -285,7 +297,7 @@ protected void checkColorConversion() { int inputValue; try { inputValue = Integer.parseInt(thresholdInput.getText()); - if (inputValue >= 0 && inputValue <= 100) { + if (inputValue >= 0 && inputValue <= 255) { AppVaribles.setUserConfigValue(ImageBinaryInputKey, inputValue + ""); } else { inputValue = -1; diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageBaseController.java b/MyBox/src/main/java/mara/mybox/controller/ImageBaseController.java index f780f8953..519db9dd0 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageBaseController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageBaseController.java @@ -17,29 +17,26 @@ import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.fxml.FXML; -import javafx.fxml.FXMLLoader; -import javafx.scene.Scene; import javafx.scene.control.Alert; import javafx.scene.control.ButtonType; import javafx.scene.control.ScrollPane; import javafx.scene.image.ImageView; import javafx.scene.layout.Pane; +import javafx.scene.layout.Region; import javafx.stage.Modality; -import javafx.stage.Stage; -import javafx.stage.StageStyle; -import javafx.stage.WindowEvent; import javax.imageio.ImageIO; -import static mara.mybox.objects.AppVaribles.logger; +import mara.mybox.fxml.FxmlStage; +import static mara.mybox.value.AppVaribles.logger; import mara.mybox.fxml.FxmlTools; -import mara.mybox.objects.ImageFileInformation; +import mara.mybox.data.ImageFileInformation; import mara.mybox.tools.FileTools; -import mara.mybox.imagefile.ImageFileReaders; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.FileInformation; -import mara.mybox.objects.ImageAttributes; -import mara.mybox.objects.ImageInformation; +import mara.mybox.image.file.ImageFileReaders; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.value.CommonValues; +import mara.mybox.data.FileInformation; +import mara.mybox.data.ImageAttributes; +import mara.mybox.data.ImageInformation; import mara.mybox.tools.DateTools; import mara.mybox.tools.ValueTools; @@ -55,6 +52,7 @@ public abstract class ImageBaseController extends BaseController { protected Image image; protected ImageAttributes attributes; protected Map sizes; + protected Map imageData; protected class ProcessParameters { @@ -107,7 +105,7 @@ protected void initializeNext2() { @FXML @Override - protected void startProcess(ActionEvent event) { + public void startAction() { isPreview = false; makeActualParameters(); currentParameters = actualParameters; @@ -133,6 +131,7 @@ public void loadImage(final File file, final boolean onlyInformation) { sourceFile = file; imageInformation = null; image = null; + imageData = null; final String fileName = file.getPath(); getMyStage().setTitle(getBaseTitle() + " " + fileName); task = new Task() { @@ -160,7 +159,7 @@ public void run() { Platform.runLater(new Runnable() { @Override public void run() { - handleMultipleImages(); + handleMultipleFramesImage(); } }); return null; @@ -204,7 +203,7 @@ public void run() { public void loadImage(final String fileName) { try { sourceFile = new File(fileName).getAbsoluteFile(); // Must convert to AbsoluteFile! -// popInformation(fileName + "\n" + sourceFile.getAbsolutePath()); +// infoAction(fileName + "\n" + sourceFile.getAbsolutePath()); if (sourceFileInput != null) { sourceFileInput.setText(sourceFile.getAbsolutePath()); } else { @@ -215,10 +214,20 @@ public void loadImage(final String fileName) { } } + public void loadImage(File sourceFile, Image image, ImageInformation imageInformation, + Map imageData) { + this.sourceFile = sourceFile; + this.imageInformation = imageInformation; + this.image = image; + this.imageData = imageData; + afterImageLoaded(); + } + public void loadImage(File sourceFile, Image image, ImageInformation imageInformation) { this.sourceFile = sourceFile; this.imageInformation = imageInformation; this.image = image; + imageData = null; afterImageLoaded(); } @@ -226,12 +235,14 @@ public void loadImage(ImageInformation imageInformation) { this.sourceFile = new File(imageInformation.getFilename()); this.imageInformation = imageInformation; this.image = imageInformation.getImage(); + imageData = null; afterImageLoaded(); } public void loadImage(final Image inImage) { sourceFile = null; imageInformation = null; + imageData = null; image = inImage; afterImageLoaded(); } @@ -244,76 +255,36 @@ protected void afterImageLoaded() { } - protected void handleMultipleImages() { + protected void handleMultipleFramesImage() { } protected void showImageInformation(ImageInformation info) { - try { - if (info == null) { - return; - } - FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(CommonValues.ImageInformationFxml), AppVaribles.CurrentBundle); - Pane root = fxmlLoader.load(); - final ImageInformationController controller = fxmlLoader.getController(); - Stage imageInformationStage = new Stage(); - controller.setMyStage(imageInformationStage); - imageInformationStage.setOnCloseRequest(new EventHandler() { - @Override - public void handle(WindowEvent event) { - if (!controller.stageClosing()) { - event.consume(); - } - } - }); - - imageInformationStage.setTitle(getMyStage().getTitle()); - imageInformationStage.initModality(Modality.NONE); - imageInformationStage.initStyle(StageStyle.DECORATED); - imageInformationStage.initOwner(null); - imageInformationStage.getIcons().add(CommonValues.AppIcon); - imageInformationStage.setScene(new Scene(root)); - imageInformationStage.show(); - - controller.loadInformation(info); - - } catch (Exception e) { - logger.error(e.toString()); + if (info == null) { + return; } + FxmlStage.openImageInformation(getClass(), null, info); } protected void showImageMetaData(ImageInformation info) { - try { - if (info == null) { - return; - } - FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(CommonValues.ImageMetaDataFxml), AppVaribles.CurrentBundle); - Pane root = fxmlLoader.load(); - final ImageMetaDataController controller = fxmlLoader.getController(); - Stage imageInformationStage = new Stage(); - controller.setMyStage(imageInformationStage); - imageInformationStage.setOnCloseRequest(new EventHandler() { - @Override - public void handle(WindowEvent event) { - if (!controller.stageClosing()) { - event.consume(); - } - } - }); - - imageInformationStage.setTitle(getMyStage().getTitle()); - imageInformationStage.initModality(Modality.NONE); - imageInformationStage.initStyle(StageStyle.DECORATED); - imageInformationStage.initOwner(null); - imageInformationStage.getIcons().add(CommonValues.AppIcon); - imageInformationStage.setScene(new Scene(root)); - imageInformationStage.show(); + if (info == null) { + return; + } + FxmlStage.openImageMetaData(getClass(), null, info); + } - controller.loadData(info); + protected void showImageStatistic(ImageInformation info) { + if (info == null) { + return; + } + FxmlStage.openImageStatistic(getClass(), null, info); + } - } catch (Exception e) { - logger.error(e.toString()); + protected void showImageStatistic(Image image) { + if (image == null) { + return; } + FxmlStage.openImageStatistic(getClass(), null, image); } protected void multipleFilesGenerated(final List fileNames) { @@ -338,6 +309,7 @@ protected void multipleFilesGenerated(final List fileNames) { } getMyStage(); alert.setContentText(info); + alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); ButtonType buttonOpen = new ButtonType(AppVaribles.getMessage("OpenTargetPath")); ButtonType buttonBrowse = new ButtonType(AppVaribles.getMessage("Browse")); ButtonType buttonBrowseNew = new ButtonType(AppVaribles.getMessage("BrowseInNew")); @@ -347,31 +319,15 @@ protected void multipleFilesGenerated(final List fileNames) { if (result.get() == buttonOpen) { Desktop.getDesktop().browse(new File(path).toURI()); } else if (result.get() == buttonBrowse) { - FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(CommonValues.ImagesViewerFxml), AppVaribles.CurrentBundle); - Pane pane = fxmlLoader.load(); - final ImagesViewerController controller = fxmlLoader.getController(); - controller.setMyStage(myStage); - myStage.setScene(new Scene(pane)); - controller.setBaseTitle(AppVaribles.getMessage("MultipleImagesViewer")); - controller.loadImages(fileNames); + final ImagesBrowserController controller = FxmlStage.openImagesBrowser(getClass(), getMyStage()); + if (controller != null && sourceFile != null) { + controller.loadImages(fileNames); + } } else if (result.get() == buttonBrowseNew) { - FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(CommonValues.ImagesViewerFxml), AppVaribles.CurrentBundle); - Pane pane = fxmlLoader.load(); - final ImagesViewerController controller = fxmlLoader.getController(); - Stage stage = new Stage(); - controller.setMyStage(stage); - stage.setOnCloseRequest(new EventHandler() { - @Override - public void handle(WindowEvent event) { - if (!controller.stageClosing()) { - event.consume(); - } - } - }); - stage.setScene(new Scene(pane)); - stage.show(); - controller.setBaseTitle(AppVaribles.getMessage("MultipleImagesViewer")); - controller.loadImages(fileNames); + final ImagesBrowserController controller = FxmlStage.openImagesBrowser(getClass(), null); + if (controller != null && sourceFile != null) { + controller.loadImages(fileNames); + } } } catch (Exception e) { @@ -533,7 +489,7 @@ public void handle(ActionEvent event) { || !new File(currentParameters.finalTargetName).exists()) { alertInformation(AppVaribles.getMessage("NoDataNotSupported")); } else { - openImageManufacture(currentParameters.finalTargetName); + openImageViewer(currentParameters.finalTargetName); } } @@ -552,7 +508,7 @@ public void handle(ActionEvent event) { operationBarController.pauseButton.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { - startProcess(event); + startAction(); } }); paraBox.setDisable(true); @@ -561,7 +517,7 @@ public void handle(ActionEvent event) { operationBarController.startButton.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { - startProcess(event); + startAction(); } }); operationBarController.pauseButton.setVisible(false); @@ -679,4 +635,12 @@ public void setSizes(Map sizes) { this.sizes = sizes; } + public Map getImageData() { + return imageData; + } + + public void setImageData(Map imageData) { + this.imageData = imageData; + } + } diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageConverterAttributesController.java b/MyBox/src/main/java/mara/mybox/controller/ImageConverterAttributesController.java index 7f649b65a..9cbba1bc0 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageConverterAttributesController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageConverterAttributesController.java @@ -18,12 +18,12 @@ import javafx.stage.Modality; import javafx.stage.Stage; import javafx.stage.WindowEvent; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.image.ImageConvertTools.KeepRatioType; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.ImageAttributes; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.image.ImageConvert.KeepRatioType; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.value.CommonValues; +import mara.mybox.data.ImageAttributes; import mara.mybox.fxml.FxmlTools; import static mara.mybox.fxml.FxmlTools.badStyle; diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageConverterBatchController.java b/MyBox/src/main/java/mara/mybox/controller/ImageConverterBatchController.java index 19bf36c44..3bafaf69f 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageConverterBatchController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageConverterBatchController.java @@ -2,8 +2,8 @@ import javafx.beans.binding.Bindings; import javafx.beans.property.SimpleBooleanProperty; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.AppVaribles; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.AppVaribles; import static mara.mybox.fxml.FxmlTools.badStyle; /** diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageConverterController.java b/MyBox/src/main/java/mara/mybox/controller/ImageConverterController.java index 67dfd61d8..72c48c5ce 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageConverterController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageConverterController.java @@ -10,11 +10,11 @@ import javafx.fxml.FXML; import javafx.scene.control.Button; import javax.imageio.ImageIO; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.image.ImageConvertTools; -import mara.mybox.imagefile.ImageFileWriters; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.ImageAttributes; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.image.ImageConvert; +import mara.mybox.image.file.ImageFileWriters; +import mara.mybox.value.AppVaribles; +import mara.mybox.data.ImageAttributes; import mara.mybox.tools.FileTools; import static mara.mybox.fxml.FxmlTools.badStyle; import org.apache.pdfbox.rendering.ImageType; @@ -57,7 +57,7 @@ protected void initializeNext2() { @FXML protected void showImage(ActionEvent event) { - openImageManufacture(sourceFile.getAbsolutePath()); + openImageViewer(sourceFile.getAbsolutePath()); } @Override @@ -160,7 +160,7 @@ private boolean handleCurrentFile() { if (currentParameters.finalTargetName == null) { return false; } - bufferedImage = ImageConvertTools.scaleImage(bufferedImage, w, h); + bufferedImage = ImageConvert.scaleImage(bufferedImage, w, h); bufferedImage = ImageFileWriters.convertColor(bufferedImage, attributes); ImageFileWriters.writeImageFile(bufferedImage, attributes, currentParameters.finalTargetName); return true; @@ -208,7 +208,7 @@ protected String makeFilename(int w, int h) { if (attributes.getBinaryConversion() == ImageAttributes.BinaryConversion.BINARY_THRESHOLD) { fname += "_" + "BINARY-Threshold"; if (attributes.getThreshold() >= 0) { - fname += "-" + attributes.getThreshold() + "%"; + fname += "-" + attributes.getThreshold(); } } else if (attributes.getBinaryConversion() == ImageAttributes.BinaryConversion.BINARY_OTSU) { fname += "_" + "BINARY-OTSU"; diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageFramesViewerController.java b/MyBox/src/main/java/mara/mybox/controller/ImageFramesViewerController.java index 66e0e3ac3..30c101bf0 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageFramesViewerController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageFramesViewerController.java @@ -32,14 +32,14 @@ import javafx.stage.FileChooser; import javafx.stage.Modality; import javafx.util.Callback; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.imagefile.ImageFileReaders; -import mara.mybox.imagefile.ImageFileWriters; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.CommonValues; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.ImageFileInformation; -import mara.mybox.objects.ImageInformation; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.image.file.ImageFileReaders; +import mara.mybox.image.file.ImageFileWriters; +import mara.mybox.value.AppVaribles; +import mara.mybox.value.CommonValues; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.data.ImageFileInformation; +import mara.mybox.data.ImageInformation; import mara.mybox.tools.FileTools; import mara.mybox.tools.ValueTools; @@ -52,12 +52,12 @@ public class ImageFramesViewerController extends ImageBaseController { protected SimpleBooleanProperty changed; - protected boolean isSettingValues; + protected ObservableList sourceImages = FXCollections.observableArrayList(); @FXML - protected Button extractButton, infoButton, metaButton, viewButton, editButton; + protected Button extractButton, metaButton, viewButton, editButton; @FXML protected TableView sourceTable; @FXML @@ -196,8 +196,10 @@ protected void checkTableSelected() { protected void openAction(ActionEvent event) { try { final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(sourcePathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(sourcePathKey); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } fileChooser.getExtensionFilters().addAll(fileExtensionFilter); final File file = fileChooser.showOpenDialog(getMyStage()); if (file == null) { @@ -328,7 +330,8 @@ protected boolean hasSampled() { } @FXML - protected void showInfo() { + @Override + public void infoAction() { showImageInformation(sourceTable.getSelectionModel().getSelectedItem()); } @@ -396,8 +399,10 @@ protected void extractAction() { } final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(targetPathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(targetPathKey); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } fileChooser.getExtensionFilters().addAll(CommonValues.ImageExtensionFilter); fileChooser.setTitle(getMessage("FilePrefixInput")); final File targetFile = fileChooser.showSaveDialog(getMyStage()); @@ -418,7 +423,7 @@ protected Void call() throws Exception { if (task.isCancelled()) { return null; } - filename = filePrefix + "-" + ValueTools.fillNumber(i, digit) + "." + format; + filename = filePrefix + "-" + ValueTools.fillLeftZero(i, digit) + "." + format; BufferedImage bufferedImage = ImageFileReaders.getBufferedImage(selectedImages.get(i)); if (bufferedImage == null) { continue; diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageGifEditerController.java b/MyBox/src/main/java/mara/mybox/controller/ImageGifEditerController.java index 8d0c72e8b..a38869f77 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageGifEditerController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageGifEditerController.java @@ -16,12 +16,12 @@ import javafx.scene.control.Toggle; import javafx.scene.control.ToggleGroup; import javafx.stage.Modality; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.logger; import static mara.mybox.fxml.FxmlTools.badStyle; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.CommonValues; -import mara.mybox.imagefile.ImageGifFile; -import static mara.mybox.objects.AppVaribles.getMessage; +import mara.mybox.value.AppVaribles; +import mara.mybox.value.CommonValues; +import mara.mybox.image.file.ImageGifFile; +import static mara.mybox.value.AppVaribles.getMessage; /** * @Author Mara diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageGifViewerController.java b/MyBox/src/main/java/mara/mybox/controller/ImageGifViewerController.java index a5d6c3295..02eeb592b 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageGifViewerController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageGifViewerController.java @@ -21,13 +21,13 @@ import javafx.scene.image.Image; import javafx.scene.layout.HBox; import javafx.stage.Modality; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.logger; import static mara.mybox.fxml.FxmlTools.badStyle; -import mara.mybox.imagefile.ImageFileReaders; -import mara.mybox.imagefile.ImageGifFile; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.ImageFileInformation; +import mara.mybox.image.file.ImageFileReaders; +import mara.mybox.image.file.ImageGifFile; +import mara.mybox.value.AppVaribles; +import mara.mybox.value.CommonValues; +import mara.mybox.data.ImageFileInformation; import mara.mybox.tools.FileTools; /** @@ -40,14 +40,13 @@ public class ImageGifViewerController extends ImageViewerController { protected Image[] images; protected int currentIndex, interval, fromIndex, toIndex, totalNumber; - protected boolean isSettingValues; @FXML protected ComboBox intervalCBox, frameBox; @FXML protected Button pauseButton, extractButton; @FXML - protected HBox opBox, extractBox; + protected HBox operation4Box; @FXML protected Label promptLabel, commentsLabel; @FXML @@ -56,15 +55,20 @@ public class ImageGifViewerController extends ImageViewerController { protected TextField fromInput, toInput; public ImageGifViewerController() { + TipsLabelKey = "GifViewTips"; + fileExtensionFilter = CommonValues.GifExtensionFilter; } @Override protected void initializeNext2() { try { - infoBar.setDisable(true); - opBox.setDisable(true); - extractBox.setDisable(true); + operation3Box.disableProperty().bind( + Bindings.isNull(imageView.imageProperty()) + ); + operation4Box.disableProperty().bind( + Bindings.isNull(imageView.imageProperty()) + ); targetTypeBox.getItems().addAll(CommonValues.SupportedImages); targetTypeBox.getSelectionModel().select(0); @@ -238,14 +242,8 @@ public void afterImageLoaded() { try { super.afterImageLoaded(); if (images == null || images.length == 0) { - infoBar.setDisable(true); - opBox.setDisable(true); - extractBox.setDisable(true); return; } - infoBar.setDisable(false); - opBox.setDisable(false); - extractBox.setDisable(false); showGifImage(0); List frames = new ArrayList<>(); for (int i = 0; i < images.length; i++) { diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageInformationController.java b/MyBox/src/main/java/mara/mybox/controller/ImageInformationController.java index 779b9457b..8908fd3fa 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageInformationController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageInformationController.java @@ -9,10 +9,10 @@ import javafx.fxml.FXML; import javafx.scene.control.TextField; import javafx.scene.input.MouseEvent; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.ImageFileInformation; -import mara.mybox.objects.ImageInformation; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.data.ImageFileInformation; +import mara.mybox.data.ImageInformation; /** * @Author Mara diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureArcController.java b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureArcController.java index 4bd7a49a4..da95fce09 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureArcController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureArcController.java @@ -13,12 +13,13 @@ import javafx.scene.control.ColorPicker; import javafx.scene.control.ComboBox; import javafx.scene.image.Image; +import javafx.scene.layout.Region; import javafx.scene.paint.Color; import javafx.stage.Modality; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.CommonValues; -import mara.mybox.fxml.FxmlImageTools; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.AppVaribles; +import mara.mybox.value.CommonValues; +import mara.mybox.fxml.image.ImageTools; import static mara.mybox.fxml.FxmlTools.badStyle; /** @@ -63,17 +64,18 @@ protected void initInterface() { isSettingValues = true; - if (CommonValues.NoAlphaImages.contains(values.getImageInfo().getImageFormat())) { + if (values.getImageInfo() != null + && CommonValues.NoAlphaImages.contains(values.getImageInfo().getImageFormat())) { transForArcButton.setDisable(true); } else { transForArcButton.setDisable(false); } arcBox.getItems().clear(); - arcBox.getItems().addAll(Arrays.asList(values.getImageInfo().getWidth() / 6 + "", - values.getImageInfo().getWidth() / 8 + "", - values.getImageInfo().getWidth() / 4 + "", - values.getImageInfo().getWidth() / 10 + "", + arcBox.getItems().addAll(Arrays.asList((int)values.getImage().getWidth() / 6 + "", + (int)values.getImage().getWidth() / 8 + "", + (int)values.getImage().getWidth() / 4 + "", + (int)values.getImage().getWidth() / 10 + "", "0", "15", "30", "50", "150", "300", "10", "3")); arcBox.getSelectionModel().select(0); @@ -132,7 +134,7 @@ public void arcAction() { task = new Task() { @Override protected Void call() throws Exception { - final Image newImage = FxmlImageTools.addArc(values.getCurrentImage(), arc, arcColorPicker.getValue()); + final Image newImage = ImageTools.addArc(values.getCurrentImage(), arc, arcColorPicker.getValue()); if (task.isCancelled()) { return null; } @@ -162,11 +164,12 @@ public void arcAction2() { if (arc <= 0) { return; } - final Image newImage = FxmlImageTools.addArcFx(values.getCurrentImage(), arc, arcColorPicker.getValue()); + final Image newImage = ImageTools.addArcFx(values.getCurrentImage(), arc, arcColorPicker.getValue()); if (newImage == null) { Alert alert = new Alert(Alert.AlertType.ERROR); alert.setTitle(getMyStage().getTitle()); alert.setContentText(AppVaribles.getMessage("ErrorForBigImage")); + alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); Optional result = alert.showAndWait(); return; } diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchAddMarginsController.java b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchAddMarginsController.java index babce2363..9a95831f6 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchAddMarginsController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchAddMarginsController.java @@ -11,11 +11,11 @@ import javafx.scene.control.ColorPicker; import javafx.scene.control.ComboBox; import javafx.scene.paint.Color; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.AppVaribles; -import mara.mybox.fxml.FxmlImageTools; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.AppVaribles; +import mara.mybox.fxml.image.ImageTools; import static mara.mybox.fxml.FxmlTools.badStyle; -import mara.mybox.image.ImageMarginsTools; +import mara.mybox.image.ImageMargins; /** * @Author Mara @@ -151,8 +151,8 @@ protected BufferedImage handleImage(BufferedImage source) { if (!checkMargins()) { return null; } - BufferedImage target = ImageMarginsTools.addMargins(source, - FxmlImageTools.colorConvert(addMarginsColorPicker.getValue()), addMarginWidth, + BufferedImage target = ImageMargins.addMargins(source, + ImageTools.colorConvert(addMarginsColorPicker.getValue()), addMarginWidth, addMarginsTopCheck.isSelected(), addMarginsBottomCheck.isSelected(), addMarginsLeftCheck.isSelected(), addMarginsRightCheck.isSelected()); diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchArcController.java b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchArcController.java index 3dcb7bb55..fa7c887fe 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchArcController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchArcController.java @@ -15,10 +15,10 @@ import javafx.scene.control.Tooltip; import javafx.scene.paint.Color; import javafx.scene.text.Font; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.image.ImageConvertTools; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.fxml.FxmlImageTools; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.image.ImageConvert; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.fxml.image.ImageTools; import mara.mybox.fxml.FxmlTools; import static mara.mybox.fxml.FxmlTools.badStyle; @@ -181,8 +181,8 @@ protected BufferedImage handleImage(BufferedImage source) { if (isPercent) { value = source.getWidth() * percent / 100; } - BufferedImage target = ImageConvertTools.addArc(source, value, - FxmlImageTools.colorConvert(arcColorPicker.getValue())); + BufferedImage target = ImageConvert.addArc(source, value, + ImageTools.colorConvert(arcColorPicker.getValue())); return target; } catch (Exception e) { logger.error(e.toString()); diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchColorController.java b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchColorController.java index 63bd93f46..0241cf81e 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchColorController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchColorController.java @@ -11,12 +11,13 @@ import javafx.scene.control.TextField; import javafx.scene.control.Toggle; import javafx.scene.control.ToggleGroup; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.fxml.FxmlAdjustColorTools.ColorActionType; -import mara.mybox.fxml.FxmlAdjustColorTools.ColorObjectType; -import static mara.mybox.objects.AppVaribles.getMessage; +import static mara.mybox.value.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.getMessage; import static mara.mybox.fxml.FxmlTools.badStyle; -import mara.mybox.image.ImageAdjustColorTools; +import mara.mybox.image.PixelsOperation; +import mara.mybox.image.ImageScope; +import mara.mybox.image.PixelsOperation.ColorActionType; +import mara.mybox.image.PixelsOperation.OperationType; /** * @Author Mara @@ -28,7 +29,7 @@ public class ImageManufactureBatchColorController extends ImageManufactureBatchC private int colorValue; private boolean isIncrease; - private ColorObjectType colorOperationType; + private OperationType colorOperationType; private ColorActionType colorActionType; @FXML @@ -70,10 +71,10 @@ protected void initOptionsSection() { @Override public void changed(ObservableValue ov, Toggle old_toggle, Toggle new_toggle) { - checkColorObjectType(); + checkOperationType(); } }); - checkColorObjectType(); + checkOperationType(); colorSlider.valueProperty().addListener(new ChangeListener() { @Override @@ -106,7 +107,7 @@ public void changed(ObservableValue ov, } } - private void checkColorObjectType() { + private void checkOperationType() { setRadio.setDisable(false); invertRadio.setDisable(false); @@ -116,7 +117,7 @@ private void checkColorObjectType() { setRadio.setSelected(true); RadioButton selected = (RadioButton) colorGroup.getSelectedToggle(); if (getMessage("Brightness").equals(selected.getText())) { - colorOperationType = ColorObjectType.Brightness; + colorOperationType = OperationType.Brightness; colorSlider.setMax(100); colorSlider.setMin(1); colorSlider.setBlockIncrement(1); @@ -127,7 +128,7 @@ private void checkColorObjectType() { filterRadio.setDisable(true); invertRadio.setDisable(true); } else if (getMessage("Saturation").equals(selected.getText())) { - colorOperationType = ColorObjectType.Sauration; + colorOperationType = OperationType.Sauration; colorSlider.setMax(100); colorSlider.setMin(1); colorSlider.setBlockIncrement(1); @@ -138,7 +139,7 @@ private void checkColorObjectType() { filterRadio.setDisable(true); invertRadio.setDisable(true); } else if (getMessage("Hue").equals(selected.getText())) { - colorOperationType = ColorObjectType.Hue; + colorOperationType = OperationType.Hue; colorSlider.setMax(359); colorSlider.setMin(1); colorSlider.setBlockIncrement(1); @@ -149,7 +150,7 @@ private void checkColorObjectType() { filterRadio.setDisable(true); invertRadio.setDisable(true); } else if (getMessage("Red").equals(selected.getText())) { - colorOperationType = ColorObjectType.Red; + colorOperationType = OperationType.Red; colorSlider.setMax(255); colorSlider.setMin(1); colorSlider.setBlockIncrement(1); @@ -158,7 +159,7 @@ private void checkColorObjectType() { colorInput.setText("50"); } } else if (getMessage("Green").equals(selected.getText())) { - colorOperationType = ColorObjectType.Green; + colorOperationType = OperationType.Green; colorSlider.setMax(255); colorSlider.setMin(1); colorSlider.setBlockIncrement(1); @@ -167,7 +168,7 @@ private void checkColorObjectType() { colorInput.setText("50"); } } else if (getMessage("Blue").equals(selected.getText())) { - colorOperationType = ColorObjectType.Blue; + colorOperationType = OperationType.Blue; colorSlider.setMax(255); colorSlider.setMin(1); colorSlider.setBlockIncrement(1); @@ -176,7 +177,7 @@ private void checkColorObjectType() { colorInput.setText("50"); } } else if (getMessage("Yellow").equals(selected.getText())) { - colorOperationType = ColorObjectType.Yellow; + colorOperationType = OperationType.Yellow; colorSlider.setMax(255); colorSlider.setMin(1); colorSlider.setBlockIncrement(1); @@ -185,7 +186,7 @@ private void checkColorObjectType() { colorInput.setText("50"); } } else if (getMessage("Cyan").equals(selected.getText())) { - colorOperationType = ColorObjectType.Cyan; + colorOperationType = OperationType.Cyan; colorSlider.setMax(255); colorSlider.setMin(1); colorSlider.setBlockIncrement(1); @@ -194,7 +195,7 @@ private void checkColorObjectType() { colorInput.setText("50"); } } else if (getMessage("Magenta").equals(selected.getText())) { - colorOperationType = ColorObjectType.Magenta; + colorOperationType = OperationType.Magenta; colorSlider.setMax(255); colorSlider.setMin(1); colorSlider.setBlockIncrement(1); @@ -203,7 +204,7 @@ private void checkColorObjectType() { colorInput.setText("50"); } } else if (getMessage("Opacity").equals(selected.getText())) { - colorOperationType = ColorObjectType.Opacity; + colorOperationType = OperationType.Opacity; colorSlider.setMax(100); colorSlider.setMin(0); colorSlider.setBlockIncrement(1); @@ -216,7 +217,7 @@ private void checkColorObjectType() { increaseRadio.setDisable(true); decreaseRadio.setDisable(true); } else if (getMessage("RGB").equals(selected.getText())) { - colorOperationType = ColorObjectType.RGB; + colorOperationType = OperationType.RGB; colorSlider.setMax(255); colorSlider.setMin(1); colorSlider.setBlockIncrement(1); @@ -267,20 +268,14 @@ protected BufferedImage handleImage(BufferedImage source) { return null; } try { - float value = colorValue; - if (colorActionType == ColorActionType.Decrease) { - value = 0 - colorValue; - } + ImageScope scope = new ImageScope(); + PixelsOperation pixelsOperation = new PixelsOperation(source, scope, + colorOperationType, colorActionType); switch (colorOperationType) { + case Hue: case Brightness: case Sauration: - value = value / 100.0f; - break; - case Opacity: - value = value * 255 / 100.0f; - break; - case Hue: - value = value / 360.0f; + pixelsOperation.setFloatPara1(colorValue / 100.0f); break; case Red: case Green: @@ -289,9 +284,11 @@ protected BufferedImage handleImage(BufferedImage source) { case Cyan: case Magenta: case RGB: + case Opacity: + pixelsOperation.setIntPara1(colorValue); break; } - BufferedImage target = ImageAdjustColorTools.changeColor(source, colorOperationType, colorActionType, value); + BufferedImage target = pixelsOperation.operate(); return target; } catch (Exception e) { logger.error(e.toString()); diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchController.java b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchController.java index 04e4e4aa1..4877ce0ae 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchController.java @@ -16,8 +16,6 @@ import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.fxml.FXML; -import javafx.fxml.FXMLLoader; -import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.RadioButton; import javafx.scene.control.SelectionMode; @@ -29,18 +27,15 @@ import javafx.scene.control.Tooltip; import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.input.MouseEvent; -import javafx.scene.layout.Pane; import javafx.scene.text.Font; import javafx.stage.FileChooser; -import javafx.stage.Stage; -import javafx.stage.WindowEvent; import javax.imageio.ImageIO; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.imagefile.ImageFileWriters; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.FileInformation; +import mara.mybox.fxml.FxmlStage; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.image.file.ImageFileWriters; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.data.FileInformation; import mara.mybox.tools.FileTools; import mara.mybox.fxml.FxmlTools; import static mara.mybox.fxml.FxmlTools.badStyle; @@ -68,7 +63,7 @@ public class ImageManufactureBatchController extends ImageBaseController { @FXML protected TextField targetSuffixInput; @FXML - protected Button addButton, upButton, downButton, deleteButton, clearButton, browseButton, openButton, insertButton; + protected Button addButton, upButton, downButton, clearButton, browseButton, openButton, insertButton; @FXML protected RadioButton blackRadio, whiteRadio; @@ -189,7 +184,7 @@ public void changed(ObservableValue observable, String oldValu } } }); - targetPathInput.setText(AppVaribles.getUserConfigValue(targetPathKey, CommonValues.UserFilePath)); + targetPathInput.setText(AppVaribles.getUserConfigPath(targetPathKey).getAbsolutePath()); targetExistGroup.selectedToggleProperty().addListener(new ChangeListener() { @Override @@ -273,8 +268,10 @@ void insertAction(ActionEvent event) { protected void addAction(int index) { try { final FileChooser fileChooser = new FileChooser(); - File defaultPath = new File(AppVaribles.getUserConfigPath(sourcePathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(defaultPath); + File defaultPath = AppVaribles.getUserConfigPath(sourcePathKey); + if (defaultPath.exists()) { + fileChooser.setInitialDirectory(defaultPath); + } fileChooser.getExtensionFilters().addAll(fileExtensionFilter); List files = fileChooser.showOpenMultipleDialog(getMyStage()); @@ -306,7 +303,8 @@ protected void addAction(int index) { } @FXML - protected void deleteAction(ActionEvent event) { + @Override + public void deleteAction() { List selected = new ArrayList<>(); selected.addAll(sourceTable.getSelectionModel().getSelectedIndices()); if (selected.isEmpty()) { @@ -398,24 +396,10 @@ protected void browseAction() { if (generatedFiles == null || generatedFiles.isEmpty()) { return; } - FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(CommonValues.ImagesViewerFxml), AppVaribles.CurrentBundle); - Pane pane = fxmlLoader.load(); - final ImagesViewerController controller = fxmlLoader.getController(); - Stage stage = new Stage(); - controller.setMyStage(stage); - stage.setOnCloseRequest(new EventHandler() { - @Override - public void handle(WindowEvent event) { - if (!controller.stageClosing()) { - event.consume(); - } - } - }); - stage.setScene(new Scene(pane)); - stage.show(); - - controller.setBaseTitle(AppVaribles.getMessage("MultipleImagesViewer")); - controller.loadImages(generatedFiles); + final ImagesBrowserController controller = FxmlStage.openImagesBrowser(getClass(), null); + if (controller != null) { + controller.loadImages(generatedFiles); + } } catch (Exception e) { } } diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchConvolutionController.java b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchConvolutionController.java deleted file mode 100644 index 916c9c044..000000000 --- a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchConvolutionController.java +++ /dev/null @@ -1,125 +0,0 @@ -package mara.mybox.controller; - -import java.awt.image.BufferedImage; -import java.util.ArrayList; -import java.util.List; -import javafx.beans.binding.Bindings; -import javafx.beans.value.ChangeListener; -import javafx.beans.value.ObservableValue; -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; -import javafx.event.ActionEvent; -import javafx.fxml.FXML; -import javafx.scene.control.ComboBox; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.db.TableConvolutionKernel; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.ConvolutionKernel; -import static mara.mybox.fxml.FxmlTools.badStyle; -import mara.mybox.image.ImageEffectTools; - -/** - * @Author Mara - * @CreateDate 2018-11-08 - * @Description - * @License Apache License Version 2.0 - */ -public class ImageManufactureBatchConvolutionController extends ImageManufactureBatchController { - - private final ObservableList kernels = FXCollections.observableArrayList(); - private ConvolutionKernel currentKernel; - private boolean isSettingValues; - - @FXML - private ComboBox kernelBox; - - public ImageManufactureBatchConvolutionController() { - - } - - @Override - protected void initializeNext2() { - try { - - operationBarController.startButton.disableProperty().bind(Bindings.isEmpty(targetPathInput.textProperty()) - .or(targetPathInput.styleProperty().isEqualTo(badStyle)) - .or(Bindings.isEmpty(sourceFilesInformation)) - .or(Bindings.isEmpty(kernels)) - ); - - } catch (Exception e) { - logger.debug(e.toString()); - } - } - - @Override - protected void initOptionsSection() { - try { - - kernelBox.setVisibleRowCount(10); - kernelBox.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue ov, Number oldValue, Number newValue) { - if (isSettingValues) { - return; - } - int index = newValue.intValue(); - if (index < 0 || index >= kernels.size()) { - return; - } - currentKernel = kernels.get(index); - } - }); - kernels.addAll(TableConvolutionKernel.read()); - loadList(); - - } catch (Exception e) { - logger.error(e.toString()); - } - } - - public void loadList(List records) { - kernels.clear(); - kernels.addAll(records); - loadList(); - } - - public void loadList() { - isSettingValues = true; - kernelBox.getItems().clear(); - if (kernels == null || kernels.isEmpty()) { - isSettingValues = false; - return; - } - List names = new ArrayList<>(); - for (ConvolutionKernel k : kernels) { - names.add(k.getName()); - } - kernelBox.getItems().addAll(names); - isSettingValues = false; - - kernelBox.getSelectionModel().select(0); - } - - @FXML - private void manageKernels(ActionEvent event) { - BaseController c = openStage(CommonValues.ConvolutionKernelManagerFxml, true); - c.setParentController(getMyController()); - c.setParentFxml(getMyFxml()); - } - - @Override - protected BufferedImage handleImage(BufferedImage source) { - if (currentKernel == null) { - return null; - } - try { - BufferedImage target = ImageEffectTools.applyConvolution(source, currentKernel); - return target; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - } - -} diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchCropController.java b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchCropController.java index 024f043ed..2d3ea5f28 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchCropController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchCropController.java @@ -9,9 +9,9 @@ import javafx.scene.control.TextField; import javafx.scene.control.Toggle; import javafx.scene.control.ToggleGroup; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.image.ImageConvertTools; -import mara.mybox.objects.AppVaribles; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.image.ImageConvert; +import mara.mybox.value.AppVaribles; import static mara.mybox.fxml.FxmlTools.badStyle; /** @@ -260,7 +260,7 @@ protected BufferedImage handleImage(BufferedImage source) { errorString = AppVaribles.getMessage("BeyondSize"); return null; } - return ImageConvertTools.cropImage(source, x1, y1, x2, y2); + return ImageConvert.cropImage(source, x1, y1, x2, y2); } catch (Exception e) { logger.error(e.toString()); return null; diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchCutMarginsController.java b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchCutMarginsController.java index 468853666..b9dfd874f 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchCutMarginsController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchCutMarginsController.java @@ -14,13 +14,13 @@ import javafx.scene.control.Toggle; import javafx.scene.control.ToggleGroup; import javafx.scene.paint.Color; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.fxml.FxmlImageTools; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.fxml.image.ImageTools; import mara.mybox.fxml.FxmlTools; import static mara.mybox.fxml.FxmlTools.badStyle; -import mara.mybox.image.ImageMarginsTools; +import mara.mybox.image.ImageMargins; /** * @Author Mara @@ -195,13 +195,13 @@ protected BufferedImage handleImage(BufferedImage source) { } BufferedImage target; if (cutMarginsByWidth) { - target = ImageMarginsTools.cutMargins(source, + target = ImageMargins.cutMargins(source, cutMarginWidth, cutMarginsTopCheck.isSelected(), cutMarginsBottomCheck.isSelected(), cutMarginsLeftCheck.isSelected(), cutMarginsRightCheck.isSelected()); } else { - target = ImageMarginsTools.cutMargins(source, - FxmlImageTools.colorConvert(cutMarginsColorPicker.getValue()), + target = ImageMargins.cutMargins(source, + ImageTools.colorConvert(cutMarginsColorPicker.getValue()), cutMarginsTopCheck.isSelected(), cutMarginsBottomCheck.isSelected(), cutMarginsLeftCheck.isSelected(), cutMarginsRightCheck.isSelected()); } diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchEffectsController.java b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchEffectsController.java index 9c67875b9..cd0cb462c 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchEffectsController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchEffectsController.java @@ -1,30 +1,42 @@ package mara.mybox.controller; import java.awt.image.BufferedImage; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import javafx.beans.binding.Bindings; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; import javafx.fxml.FXML; +import javafx.scene.control.Button; import javafx.scene.control.CheckBox; import javafx.scene.control.ComboBox; import javafx.scene.control.Label; import javafx.scene.control.RadioButton; -import javafx.scene.control.Slider; import javafx.scene.control.TextField; import javafx.scene.control.Toggle; import javafx.scene.control.ToggleGroup; import javafx.scene.control.Tooltip; +import javafx.scene.input.KeyEvent; import javafx.scene.layout.HBox; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.fxml.FxmlEffectTools.EffectsOperationType; -import mara.mybox.image.ImageConvertTools; -import static mara.mybox.objects.AppVaribles.getMessage; +import mara.mybox.db.TableConvolutionKernel; +import mara.mybox.image.ImageConvert; import mara.mybox.fxml.FxmlTools; import static mara.mybox.fxml.FxmlTools.badStyle; -import mara.mybox.image.ImageEffectTools; -import mara.mybox.image.ImageGrayTools; -import mara.mybox.objects.ConvolutionKernel; +import mara.mybox.image.ImageBinary; +import mara.mybox.image.ImageConvolution; +import mara.mybox.image.ImageQuantization; +import mara.mybox.image.ImageContrast; +import mara.mybox.image.ImageGray; +import mara.mybox.image.ImageQuantization.QuantizationAlgorithm; +import mara.mybox.image.PixelsOperation; +import mara.mybox.image.PixelsOperation.OperationType; +import static mara.mybox.value.AppVaribles.getMessage; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.CommonValues; +import mara.mybox.data.ConvolutionKernel; /** * @Author Mara @@ -34,25 +46,27 @@ */ public class ImageManufactureBatchEffectsController extends ImageManufactureBatchController { - private EffectsOperationType effectType; - protected int threadholding, threadholdingMin, threadholdingMax, intValue, direction, bwValue; + private OperationType effectType; + protected int intPara1, intPara2, intPara3; + private List kernels; + private ConvolutionKernel kernel; + private ComboBox intBox, stringBox; + private Label intLabel, intLabel2, intLabel3, intLabel4, stringLabel; + private CheckBox valueCheck; + private TextField intInput, intInput2, intInput3, intInput4; + private RadioButton radio1, radio2, radio3, radio4; + private ToggleGroup radioGroup; + private Button setButton; + private QuantizationAlgorithm quantizationAlgorithm; + private ImageContrast.ContrastAlgorithm contrastAlgorithm; @FXML protected ToggleGroup effectsGroup; @FXML - protected HBox thresholdingBox, bwBox; + protected HBox setBox; @FXML - protected ComboBox intBox, stringBox; - @FXML - protected TextField thresholdingInput, thresholdingMinInput, thresholdingMaxInput, bwInput; - @FXML - protected RadioButton thresholdingRadio; - @FXML - protected Label intLabel, stringLabel, bwLabel1, bwLabel2, bwLabel3; - @FXML - protected CheckBox grayCheck; - @FXML - private Slider bwSlider; + protected RadioButton thresholdingRadio, posterizingRadio, bwRadio, + convolutionRadio, contrastRadio; public ImageManufactureBatchEffectsController() { @@ -61,15 +75,6 @@ public ImageManufactureBatchEffectsController() { @Override protected void initializeNext2() { try { - - operationBarController.startButton.disableProperty().bind(Bindings.isEmpty(targetPathInput.textProperty()) - .or(targetPathInput.styleProperty().isEqualTo(badStyle)) - .or(Bindings.isEmpty(sourceFilesInformation)) - .or(thresholdingInput.styleProperty().isEqualTo(badStyle)) - .or(thresholdingMinInput.styleProperty().isEqualTo(badStyle)) - .or(thresholdingMaxInput.styleProperty().isEqualTo(badStyle)) - ); - } catch (Exception e) { logger.debug(e.toString()); } @@ -88,45 +93,159 @@ public void changed(ObservableValue ov, }); checkEffetcsOperationType(); + FxmlTools.setComments(thresholdingRadio, new Tooltip(getMessage("ThresholdingComments"))); + FxmlTools.setComments(posterizingRadio, new Tooltip(getMessage("QuantizationComments"))); + FxmlTools.setComments(bwRadio, new Tooltip(getMessage("BWThresholdComments"))); + + } catch (Exception e) { + logger.error(e.toString()); + } + } + + private void removeTmpControls() { + intBox = null; + valueCheck = null; + intInput = intInput2 = intInput3 = intInput4 = null; + intLabel = intLabel2 = intLabel3 = intLabel4 = stringLabel = null; + radio1 = radio2 = radio3 = radio4 = null; + setButton = null; + } + + private void checkEffetcsOperationType() { + try { + setBox.getChildren().clear(); + operationBarController.startButton.disableProperty().unbind(); + removeTmpControls(); + stringBox = null; + radioGroup = null; + + RadioButton selected = (RadioButton) effectsGroup.getSelectedToggle(); + String selectedString = selected.getText(); + if (getMessage("Blur").equals(selectedString)) { + effectType = OperationType.Blur; + makeBlurBox(); + + } else if (getMessage("Sharpen").equals(selectedString)) { + effectType = OperationType.Sharpen; + bindStart(); + + } else if (getMessage("Clarity").equals(selectedString)) { + effectType = OperationType.Clarity; + bindStart(); + + } else if (getMessage("EdgeDetection").equals(selectedString)) { + effectType = OperationType.EdgeDetect; + bindStart(); + + } else if (getMessage("Emboss").equals(selectedString)) { + effectType = OperationType.Emboss; + makeEmbossBox(); + + } else if (getMessage("Posterizing").equals(selectedString)) { + effectType = OperationType.Quantization; + makePosterizingBox(); + + } else if (getMessage("Thresholding").equals(selectedString)) { + effectType = OperationType.Thresholding; + makeThresholdingBox(); + + } else if (getMessage("Gray").equals(selectedString)) { + effectType = OperationType.Gray; + bindStart(); + + } else if (getMessage("BlackOrWhite").equals(selectedString)) { + effectType = OperationType.BlackOrWhite; + makeBlackWhiteBox(); + + } else if (getMessage("Sepia").equals(selectedString)) { + effectType = OperationType.Sepia; + makeSepiaBox(); + + } else if (getMessage("Contrast").equals(selectedString)) { + effectType = OperationType.Contrast; + makeContrastBox(); + + } else if (getMessage("Convolution").equals(selectedString)) { + effectType = OperationType.Convolution; + makeConvolutionBox(); + + } + + } catch (Exception e) { + logger.error(e.toString()); + } + } + + private void bindStart() { + operationBarController.startButton.disableProperty().bind( + Bindings.isEmpty(targetPathInput.textProperty()) + .or(targetPathInput.styleProperty().isEqualTo(badStyle)) + .or(Bindings.isEmpty(sourceFilesInformation)) + ); + } + + private void makeBlurBox() { + try { + intPara1 = 10; + intLabel = new Label(getMessage("Radius")); + intBox = new ComboBox(); + intBox.setEditable(true); + intBox.setPrefWidth(80); intBox.valueProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue ov, String oldValue, String newValue) { - int defaultValue = 0; - if (null != effectType) { - switch (effectType) { - case Blur: - defaultValue = 1; - break; - case Posterizing: - defaultValue = 32; - break; - case Emboss: - defaultValue = 3; - break; - default: - break; - } - } try { - String v = newValue; - int pos = v.indexOf(" "); - if (pos > 0) { - v = v.substring(0, pos); - } - intValue = Integer.valueOf(v); - if (intValue > 0) { + int v = Integer.valueOf(newValue); + if (v > 0) { + intPara1 = v; intBox.getEditor().setStyle(null); } else { - intValue = defaultValue; intBox.getEditor().setStyle(badStyle); } } catch (Exception e) { - intValue = defaultValue; intBox.getEditor().setStyle(badStyle); } } }); + intBox.getItems().addAll(Arrays.asList("10", "5", "3", "2", "1", "8", "15", "20", "30")); + intBox.getSelectionModel().select(0); + stringLabel = new Label(getMessage("Algorithm")); + stringBox = new ComboBox(); + stringBox.valueProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue ov, String oldValue, String newValue) { + try { + if (getMessage("AverageBlur").equals(newValue)) { + kernel = ConvolutionKernel.makeAverageBlur(intPara1); + } else { + kernel = ConvolutionKernel.makeGaussKernel(intPara1); + } + stringBox.getEditor().setStyle(null); + } catch (Exception e) { + stringBox.getEditor().setStyle(badStyle); + } + } + }); + stringBox.getItems().addAll(Arrays.asList(getMessage("AverageBlur"), getMessage("GaussianBlur"))); + stringBox.getSelectionModel().select(getMessage("AverageBlur")); + setBox.getChildren().addAll(stringLabel, stringBox, intLabel, intBox); + operationBarController.startButton.disableProperty().bind( + intBox.getEditor().styleProperty().isEqualTo(badStyle) + .or(stringBox.getEditor().styleProperty().isEqualTo(badStyle)) + .or(Bindings.isEmpty(targetPathInput.textProperty())) + .or(targetPathInput.styleProperty().isEqualTo(badStyle)) + .or(Bindings.isEmpty(sourceFilesInformation)) + ); + } catch (Exception e) { + logger.error(e.toString()); + } + } + private void makeEmbossBox() { + try { + intPara1 = ImageConvert.Direction.Top; + stringLabel = new Label(getMessage("Direction")); + stringBox = new ComboBox(); stringBox.valueProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue ov, String oldValue, String newValue) { @@ -134,224 +253,488 @@ public void changed(ObservableValue ov, String oldValue, String newValue) { return; } if (getMessage("Top").equals(newValue)) { - direction = ImageConvertTools.Direction.Top; + intPara1 = ImageConvert.Direction.Top; } else if (getMessage("Bottom").equals(newValue)) { - direction = ImageConvertTools.Direction.Bottom; + intPara1 = ImageConvert.Direction.Bottom; } else if (getMessage("Left").equals(newValue)) { - direction = ImageConvertTools.Direction.Top; + intPara1 = ImageConvert.Direction.Top; } else if (getMessage("Right").equals(newValue)) { - direction = ImageConvertTools.Direction.Right; + intPara1 = ImageConvert.Direction.Right; } else if (getMessage("LeftTop").equals(newValue)) { - direction = ImageConvertTools.Direction.LeftTop; + intPara1 = ImageConvert.Direction.LeftTop; } else if (getMessage("RightBottom").equals(newValue)) { - direction = ImageConvertTools.Direction.RightBottom; + intPara1 = ImageConvert.Direction.RightBottom; } else if (getMessage("LeftBottom").equals(newValue)) { - direction = ImageConvertTools.Direction.LeftBottom; + intPara1 = ImageConvert.Direction.LeftBottom; } else if (getMessage("RightTop").equals(newValue)) { - direction = ImageConvertTools.Direction.RightTop; + intPara1 = ImageConvert.Direction.RightTop; } else { - direction = ImageConvertTools.Direction.Top; + intPara1 = ImageConvert.Direction.Top; + } + } + }); + stringBox.getItems().addAll(Arrays.asList(getMessage("Top"), getMessage("Bottom"), + getMessage("Left"), getMessage("Right"), + getMessage("LeftTop"), getMessage("RightBottom"), + getMessage("LeftBottom"), getMessage("RightTop"))); + stringBox.getSelectionModel().select(getMessage("Top")); + intPara2 = 3; + intLabel = new Label(getMessage("Radius")); + intBox = new ComboBox(); + intBox.setEditable(false); + intBox.setPrefWidth(80); + intBox.valueProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue ov, String oldValue, String newValue) { + try { + int v = Integer.valueOf(newValue); + if (v > 0) { + intPara2 = v; + intBox.getEditor().setStyle(null); + } else { + intBox.getEditor().setStyle(badStyle); + } + } catch (Exception e) { + intBox.getEditor().setStyle(badStyle); } } }); + intBox.getItems().addAll(Arrays.asList("3", "5")); + intBox.getSelectionModel().select(0); + valueCheck = new CheckBox(getMessage("Gray")); + valueCheck.setSelected(true); + setBox.getChildren().addAll(stringLabel, stringBox, intLabel, intBox, valueCheck); + operationBarController.startButton.disableProperty().bind( + intBox.getEditor().styleProperty().isEqualTo(badStyle) + .or(Bindings.isEmpty(targetPathInput.textProperty())) + .or(targetPathInput.styleProperty().isEqualTo(badStyle)) + .or(Bindings.isEmpty(sourceFilesInformation)) + .or(stringBox.getEditor().styleProperty().isEqualTo(badStyle)) + ); + } catch (Exception e) { + logger.error(e.toString()); + } + } - Tooltip tips = new Tooltip("0~255"); -// tips.setFont(new Font(16)); - FxmlTools.quickTooltip(thresholdingInput, tips); - FxmlTools.quickTooltip(thresholdingMinInput, tips); - FxmlTools.quickTooltip(thresholdingMaxInput, tips); + private void makePosterizingBox() { + try { + quantizationAlgorithm = QuantizationAlgorithm.RGB_Uniform; + stringLabel = new Label(getMessage("Algorithm")); + stringBox = new ComboBox(); + stringBox.valueProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue ov, String oldValue, String newValue) { + if (getMessage("RGBUniformQuantization").equals(newValue)) { + quantizationAlgorithm = QuantizationAlgorithm.RGB_Uniform; + } else if (getMessage("HSBUniformQuantization").equals(newValue)) { + quantizationAlgorithm = QuantizationAlgorithm.HSB_Uniform; + } + } + }); + stringBox.getItems().addAll(Arrays.asList(getMessage("RGBUniformQuantization"), + getMessage("HSBUniformQuantization"))); + stringBox.getSelectionModel().select(getMessage("RGBUniformQuantization")); + intPara1 = 64; + intLabel = new Label(getMessage("ColorsNumber")); + intBox = new ComboBox(); + intBox.setEditable(false); + intBox.setPrefWidth(120); + intBox.valueProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue ov, String oldValue, String newValue) { + try { + int v = Integer.valueOf(newValue); + if (v > 0) { + intPara1 = v; + intBox.getEditor().setStyle(null); + } else { + intBox.getEditor().setStyle(badStyle); + } + } catch (Exception e) { + intBox.getEditor().setStyle(badStyle); + } + } + }); + intBox.getItems().addAll(Arrays.asList( + "64", "512", "8", "4096", "216", "343", "27", "125", "1000", "729", "1728", "8000")); + intBox.getSelectionModel().select(0); + valueCheck = new CheckBox(getMessage("Dithering")); + valueCheck.setSelected(true); + FxmlTools.setComments(valueCheck, new Tooltip(getMessage("DitherComments"))); + setBox.getChildren().addAll(stringLabel, stringBox, intLabel, intBox, valueCheck); + operationBarController.startButton.disableProperty().bind( + intBox.getEditor().styleProperty().isEqualTo(badStyle) + .or(Bindings.isEmpty(targetPathInput.textProperty())) + .or(targetPathInput.styleProperty().isEqualTo(badStyle)) + .or(Bindings.isEmpty(sourceFilesInformation)) + .or(stringBox.getEditor().styleProperty().isEqualTo(badStyle)) + ); + } catch (Exception e) { + logger.error(e.toString()); + } - tips = new Tooltip(getMessage("ThresholdingComments")); -// tips.setFont(new Font(16)); - FxmlTools.setComments(thresholdingBox, tips); - FxmlTools.setComments(thresholdingRadio, tips); + } - thresholdingInput.textProperty().addListener(new ChangeListener() { + private void makeThresholdingBox() { + try { + intPara1 = 128; + intLabel = new Label(getMessage("Threshold")); + intInput = new TextField(); + intInput.textProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue observable, String oldValue, String newValue) { - checkThresholding(); + try { + int v = Integer.valueOf(newValue); + if (v >= 0 && v <= 255) { + intPara1 = v; + intInput.setStyle(null); + } else { + popError("0~255"); + intInput.setStyle(badStyle); + } + } catch (Exception e) { + popError("0~255"); + intInput.setStyle(badStyle); + } } }); - thresholdingInput.setText("128"); + intInput.setPrefWidth(100); + intInput.setText("128"); + FxmlTools.quickTooltip(intInput, new Tooltip("0~255")); + intPara2 = 0; + Label smallValueLabel = new Label(getMessage("SmallValue")); + final TextField thresholdingMinInput = new TextField(); thresholdingMinInput.textProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue observable, String oldValue, String newValue) { - checkThresholding(); + try { + int v = Integer.valueOf(newValue); + if (v >= 0 && v <= 255) { + intPara2 = v; + thresholdingMinInput.setStyle(null); + } else { + popError("0~255"); + thresholdingMinInput.setStyle(badStyle); + } + } catch (Exception e) { + popError("0~255"); + thresholdingMinInput.setStyle(badStyle); + } } }); + thresholdingMinInput.setPrefWidth(100); thresholdingMinInput.setText("0"); + FxmlTools.quickTooltip(thresholdingMinInput, new Tooltip("0~255")); + intPara3 = 255; + Label bigValueLabel = new Label(getMessage("BigValue")); + final TextField thresholdingMaxInput = new TextField(); thresholdingMaxInput.textProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue observable, String oldValue, String newValue) { - checkThresholding(); + try { + int v = Integer.valueOf(newValue); + if (v >= 0 && v <= 255) { + intPara3 = v; + thresholdingMaxInput.setStyle(null); + } else { + popError("0~255"); + thresholdingMaxInput.setStyle(badStyle); + } + } catch (Exception e) { + popError("0~255"); + thresholdingMaxInput.setStyle(badStyle); + } } }); + thresholdingMaxInput.setPrefWidth(100); thresholdingMaxInput.setText("255"); + FxmlTools.quickTooltip(thresholdingMaxInput, new Tooltip("0~255")); + + setBox.getChildren().addAll(intLabel, intInput, + bigValueLabel, thresholdingMaxInput, + smallValueLabel, thresholdingMinInput); + operationBarController.startButton.disableProperty().bind( + intInput.styleProperty().isEqualTo(badStyle) + .or(Bindings.isEmpty(targetPathInput.textProperty())) + .or(targetPathInput.styleProperty().isEqualTo(badStyle)) + .or(Bindings.isEmpty(sourceFilesInformation)) + .or(thresholdingMinInput.styleProperty().isEqualTo(badStyle)) + .or(thresholdingMaxInput.styleProperty().isEqualTo(badStyle)) + ); + } catch (Exception e) { + logger.error(e.toString()); + } + + } - bwSlider.valueProperty().addListener(new ChangeListener() { + private void makeBlackWhiteBox() { + try { + intPara2 = 128; + intInput = new TextField(); + intInput.textProperty().addListener(new ChangeListener() { @Override - public void changed(ObservableValue observable, Number oldValue, Number newValue) { - bwValue = newValue.intValue(); - bwInput.setText(bwValue + ""); + public void changed(ObservableValue observable, + String oldValue, String newValue) { + try { + int v = Integer.valueOf(intInput.getText()); + if (v >= 0 && v <= 255) { + intPara2 = v; + intInput.setStyle(null); + } else { + intInput.setStyle(badStyle); + } + } catch (Exception e) { + intInput.setStyle(badStyle); + } } }); + intInput.setPrefWidth(100); + intInput.setText("128"); + FxmlTools.quickTooltip(intInput, new Tooltip("0~255")); - bwInput.textProperty().addListener(new ChangeListener() { + intPara1 = 1; + radioGroup = new ToggleGroup(); + radio1 = new RadioButton(getMessage("OTSU")); + radio1.setToggleGroup(radioGroup); + radio1.setUserData(1); + radio2 = new RadioButton(getMessage("Default")); + radio2.setToggleGroup(radioGroup); + radio2.setUserData(2); + radio3 = new RadioButton(getMessage("Threshold")); + radio3.setToggleGroup(radioGroup); + radio3.setUserData(3); + radioGroup.selectedToggleProperty().addListener(new ChangeListener() { @Override - public void changed(ObservableValue observable, - String oldValue, String newValue) { - checkBwInput(); + public void changed(ObservableValue ov, + Toggle old_toggle, Toggle new_toggle) { + if (radioGroup.getSelectedToggle() == null) { + return; + } + intPara1 = (int) ((RadioButton) new_toggle).getUserData(); + intInput.setDisable(intPara1 != 3); } }); + radio1.setSelected(true); + valueCheck = new CheckBox(getMessage("Dithering")); + valueCheck.setSelected(true); + FxmlTools.setComments(valueCheck, new Tooltip(getMessage("DitherComments"))); + + setBox.getChildren().addAll(radio1, radio2, radio3, intInput, valueCheck); + operationBarController.startButton.disableProperty().bind( + intInput.styleProperty().isEqualTo(badStyle) + ); } catch (Exception e) { logger.error(e.toString()); } + } - private void checkEffetcsOperationType() { - intLabel.setText(""); - intBox.setDisable(true); - stringLabel.setText(""); - stringBox.setDisable(true); - thresholdingBox.setDisable(true); - thresholdingInput.setStyle(null); - thresholdingMinInput.setStyle(null); - thresholdingMaxInput.setStyle(null); - grayCheck.setDisable(true); - bwBox.setDisable(true); - bwInput.setStyle(null); - RadioButton selected = (RadioButton) effectsGroup.getSelectedToggle(); - if (getMessage("Blur").equals(selected.getText())) { - effectType = EffectsOperationType.Blur; - intLabel.setText(getMessage("Radius")); - intBox.setDisable(false); - intBox.getItems().clear(); - intBox.getItems().addAll(Arrays.asList("10", "5", "3", "8", "15", "20", "30")); - intBox.setEditable(true); - intValue = 10; - intBox.getSelectionModel().select("10"); - } else if (getMessage("Sharpen").equals(selected.getText())) { - effectType = EffectsOperationType.Sharpen; - } else if (getMessage("Clarity").equals(selected.getText())) { - effectType = EffectsOperationType.Clarity; - } else if (getMessage("EdgeDetection").equals(selected.getText())) { - effectType = EffectsOperationType.EdgeDetect; - } else if (getMessage("Emboss").equals(selected.getText())) { - effectType = EffectsOperationType.Emboss; - intLabel.setText(getMessage("Radius")); - intBox.setDisable(false); - intBox.getItems().clear(); - intBox.getItems().addAll(Arrays.asList("3", "5")); - intBox.setEditable(false); - intValue = 3; - intBox.getSelectionModel().select("3"); - stringLabel.setText(getMessage("Direction")); - stringBox.setDisable(false); - stringBox.getItems().clear(); - stringBox.getItems().addAll(Arrays.asList(getMessage("Top"), getMessage("Bottom"), - getMessage("Left"), getMessage("Right"), - getMessage("LeftTop"), getMessage("RightBottom"), - getMessage("LeftBottom"), getMessage("RightTop"))); - direction = ImageConvertTools.Direction.Top; - stringBox.getSelectionModel().select(getMessage("Top")); - grayCheck.setDisable(false); - } else if (getMessage("Posterizing").equals(selected.getText())) { - effectType = EffectsOperationType.Posterizing; - intLabel.setText(getMessage("Size")); - intBox.setDisable(false); - intBox.getItems().clear(); - intBox.getItems().addAll(Arrays.asList("64", "32", "128", "16")); - intBox.setEditable(false); - intBox.getSelectionModel().select("64"); - } else if (getMessage("Thresholding").equals(selected.getText())) { - effectType = EffectsOperationType.Thresholding; - thresholdingBox.setDisable(false); - checkThresholding(); - } else if (getMessage("Gray").equals(selected.getText())) { - effectType = EffectsOperationType.Gray; - } else if (getMessage("BlackOrWhite").equals(selected.getText())) { - effectType = EffectsOperationType.BlackOrWhite; - bwBox.setDisable(false); - bwLabel1.setText(getMessage("Threshold")); - bwSlider.setMax(99); - bwSlider.setMin(1); - bwSlider.setBlockIncrement(1); - bwSlider.setValue(50); - bwLabel2.setText("%"); - bwLabel3.setVisible(true); - checkBwInput(); - } else if (getMessage("Sepia").equals(selected.getText())) { - effectType = EffectsOperationType.Sepia; - bwBox.setDisable(false); - bwLabel1.setText(getMessage("Intensity")); - bwSlider.setMax(255); - bwSlider.setMin(0); - bwSlider.setBlockIncrement(1); - bwSlider.setValue(80); - bwLabel2.setText(""); - bwLabel3.setVisible(false); - checkBwInput(); + private void makeSepiaBox() { + try { + intPara1 = 80; + intLabel = new Label(getMessage("Intensity")); + intInput = new TextField(); + intInput.textProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue observable, + String oldValue, String newValue) { + try { + int v = Integer.valueOf(intInput.getText()); + if (v >= 0 && v <= 255) { + intPara1 = v; + intInput.setStyle(null); + } else { + intInput.setStyle(badStyle); + popError("0~255"); + } + } catch (Exception e) { + popError("0~255"); + intInput.setStyle(badStyle); + } + } + }); + intInput.setPrefWidth(100); + intInput.setText("80"); + FxmlTools.quickTooltip(intInput, new Tooltip("0~255")); + + setBox.getChildren().addAll(intLabel, intInput); + operationBarController.startButton.disableProperty().bind( + intInput.styleProperty().isEqualTo(badStyle) + .or(Bindings.isEmpty(targetPathInput.textProperty())) + .or(targetPathInput.styleProperty().isEqualTo(badStyle)) + .or(Bindings.isEmpty(sourceFilesInformation)) + ); + } catch (Exception e) { + logger.error(e.toString()); } + } - private void checkThresholding() { + private void makeConvolutionBox() { try { - threadholding = Integer.valueOf(thresholdingInput.getText()); - if (threadholding >= 0 && threadholding <= 255) { - thresholdingInput.setStyle(null); - } else { - thresholdingInput.setStyle(badStyle); + stringLabel = new Label(getMessage("ConvolutionKernel")); + stringBox = new ComboBox(); + kernel = null; + if (kernels == null) { + kernels = TableConvolutionKernel.read(); } + loadKernelsList(kernels); + stringBox.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue ov, Number oldValue, Number newValue) { + int index = newValue.intValue(); + if (index < 0 || index >= kernels.size()) { + kernel = null; + stringBox.getEditor().setStyle(badStyle); + return; + } + kernel = kernels.get(index); + stringBox.getEditor().setStyle(null); + } + }); + FxmlTools.quickTooltip(stringBox, new Tooltip(getMessage("CTRL+k"))); + setButton = new Button(getMessage("ManageDot")); + setButton.setOnAction(new EventHandler() { + @Override + public void handle(ActionEvent event) { + BaseController c = openStage(CommonValues.ConvolutionKernelManagerFxml, false); + c.setParentController(getMyController()); + c.setParentFxml(getMyFxml()); + } + }); + setBox.getChildren().addAll(stringLabel, stringBox, setButton); + operationBarController.startButton.disableProperty().bind( + stringBox.getEditor().styleProperty().isEqualTo(badStyle) + .or(Bindings.isEmpty(targetPathInput.textProperty())) + .or(targetPathInput.styleProperty().isEqualTo(badStyle)) + .or(Bindings.isEmpty(sourceFilesInformation)) + ); } catch (Exception e) { - thresholdingInput.setStyle(badStyle); + logger.error(e.toString()); } + + } + + private void makeContrastBox() { try { - threadholdingMin = Integer.valueOf(thresholdingMinInput.getText()); - if (threadholdingMin >= 0 && threadholdingMin <= 255) { - thresholdingMinInput.setStyle(null); - } else { - thresholdingMinInput.setStyle(badStyle); - } + contrastAlgorithm = ImageContrast.ContrastAlgorithm.Gray_Histogram_Equalization; + stringLabel = new Label(getMessage("Algorithm")); + stringBox = new ComboBox(); + stringBox.getItems().addAll(Arrays.asList(getMessage("GrayHistogramEqualization"), + getMessage("GrayHistogramShifting"), + getMessage("LumaHistogramEqualization"), getMessage("BrightnessHistogramEqualization"), + getMessage("AdaptiveHistogramEqualization"))); + stringBox.getSelectionModel().select(0); + stringBox.valueProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue ov, String oldValue, String newValue) { + if (getMessage("GrayHistogramEqualization").equals(newValue)) { + contrastAlgorithm = ImageContrast.ContrastAlgorithm.Gray_Histogram_Equalization; + } else if (getMessage("GrayHistogramShifting").equals(newValue)) { + contrastAlgorithm = ImageContrast.ContrastAlgorithm.Gray_Histogram_Shifting; + } else if (getMessage("LumaHistogramEqualization").equals(newValue)) { + contrastAlgorithm = ImageContrast.ContrastAlgorithm.Luma_Histogram_Equalization; + } else if (getMessage("BrightnessHistogramEqualization").equals(newValue)) { + contrastAlgorithm = ImageContrast.ContrastAlgorithm.HSB_Histogram_Equalization; + } else if (getMessage("AdaptiveHistogramEqualization").equals(newValue)) { + contrastAlgorithm = ImageContrast.ContrastAlgorithm.Adaptive_Histogram_Equalization; + } + } + }); + + intPara1 = 80; + intLabel = new Label(getMessage("Offset")); + intInput = new TextField(); + intInput.textProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue observable, + String oldValue, String newValue) { + try { + int v = Integer.valueOf(intInput.getText()); + if (v >= 0 && v <= 255) { + intPara1 = v; + intInput.setStyle(null); + } else { + intInput.setStyle(badStyle); + popError("0~255"); + } + } catch (Exception e) { + popError("0~255"); + } + } + }); + intInput.setPrefWidth(100); + intInput.setText("80"); + FxmlTools.quickTooltip(intInput, new Tooltip("0~255")); + + setBox.getChildren().addAll(stringLabel, stringBox, intLabel, intInput); + operationBarController.startButton.disableProperty().bind( + intInput.styleProperty().isEqualTo(badStyle) + .or(stringBox.getEditor().styleProperty().isEqualTo(badStyle)) + .or(Bindings.isEmpty(targetPathInput.textProperty())) + .or(targetPathInput.styleProperty().isEqualTo(badStyle)) + .or(Bindings.isEmpty(sourceFilesInformation)) + ); } catch (Exception e) { - thresholdingMinInput.setStyle(badStyle); + logger.error(e.toString()); } - try { - threadholdingMax = Integer.valueOf(thresholdingMaxInput.getText()); - if (threadholdingMax >= 0 && threadholdingMax <= 255) { - thresholdingMaxInput.setStyle(null); - } else { - thresholdingMaxInput.setStyle(badStyle); + } + + public void applyKernel(ConvolutionKernel kernel) { + if (effectType != OperationType.Convolution || stringBox == null) { + return; + } + convolutionRadio.fire(); + if (stringBox.getItems().contains(kernel.getName())) { + stringBox.getSelectionModel().select(kernel.getName()); + } else { + stringBox.getSelectionModel().select(-1); + } + this.kernel = kernel; + okAction(); + } + + public void loadKernelsList(List records) { + if (effectType != OperationType.Convolution || stringBox == null) { + return; + } + kernels = records; + stringBox.getItems().clear(); + if (kernels != null && !kernels.isEmpty()) { + List names = new ArrayList<>(); + for (ConvolutionKernel k : kernels) { + names.add(k.getName()); } - } catch (Exception e) { - thresholdingMaxInput.setStyle(badStyle); + stringBox.getItems().addAll(names); + stringBox.getSelectionModel().select(0); + stringBox.getEditor().setStyle(null); + } else { + stringBox.getEditor().setStyle(badStyle); } } - private void checkBwInput() { - try { - if (effectType == EffectsOperationType.BlackOrWhite - && bwInput.getText().trim().isEmpty()) { - bwInput.setStyle(null); - bwValue = -1; + @Override + protected void keyEventsHandler(KeyEvent event) { + super.keyEventsHandler(event); + if (event.isControlDown()) { + String key = event.getText(); + if (key == null || key.isEmpty()) { return; } - bwValue = Integer.valueOf(bwInput.getText()); - if (bwValue >= 0 && bwValue <= bwSlider.getMax()) { - bwInput.setStyle(null); - bwSlider.setValue(bwValue); - } else { - bwValue = -1; - bwInput.setStyle(badStyle); + switch (key) { + case "k": + case "K": + if (stringBox != null) { + stringBox.show(); + } + break; } - } catch (Exception e) { - bwValue = -1; - bwInput.setStyle(badStyle); } } @@ -359,41 +742,91 @@ private void checkBwInput() { protected BufferedImage handleImage(BufferedImage source) { try { BufferedImage target = null; + PixelsOperation pixelsOperation; + ImageConvolution imageConvolution; if (null != effectType) { switch (effectType) { + case Contrast: + ImageContrast imageContrast = new ImageContrast(source, contrastAlgorithm); + imageContrast.setIntPara1(intPara1); + target = imageContrast.operate(); + break; + case Convolution: + if (kernel == null) { + int index = stringBox.getSelectionModel().getSelectedIndex(); + if (kernels == null || kernels.isEmpty() || index < 0) { + return null; + } + kernel = kernels.get(index); + } + imageConvolution = new ImageConvolution(source, kernel); + target = imageConvolution.operate(); + break; case Blur: - target = ImageEffectTools.applyConvolution(source, ConvolutionKernel.makeGaussKernel(intValue)); + if (kernel == null) { + return null; + } + imageConvolution = new ImageConvolution(source, kernel); + target = imageConvolution.operate(); break; case Sharpen: - target = ImageEffectTools.applyConvolution(source, ConvolutionKernel.makeSharpen3b()); + kernel = ConvolutionKernel.makeSharpen3b(); + imageConvolution = new ImageConvolution(source, kernel); + target = imageConvolution.operate(); break; case Clarity: - target = ImageEffectTools.applyConvolution(source, ConvolutionKernel.makeUnsharpMasking5()); + kernel = ConvolutionKernel.makeUnsharpMasking5(); + imageConvolution = new ImageConvolution(source, kernel); + target = imageConvolution.operate(); break; case EdgeDetect: - target = ImageEffectTools.applyConvolution(source, ConvolutionKernel.makeEdgeDetection3b()); + kernel = ConvolutionKernel.makeEdgeDetection3b(); + imageConvolution = new ImageConvolution(source, kernel); + target = imageConvolution.operate(); break; case Emboss: - target = ImageEffectTools.applyConvolution(source, ConvolutionKernel.makeEmbossKernel(direction, intValue, grayCheck.isSelected())); + kernel = ConvolutionKernel.makeEmbossKernel(intPara1, intPara2, valueCheck.isSelected()); + imageConvolution = new ImageConvolution(source, kernel); + target = imageConvolution.operate(); break; case Thresholding: - target = ImageEffectTools.thresholding(ImageConvertTools.removeAlpha(source), threadholding, threadholdingMin, threadholdingMax); + pixelsOperation = new PixelsOperation(ImageConvert.removeAlpha(source), effectType); + pixelsOperation.setIntPara1(intPara1); + pixelsOperation.setIntPara2(intPara2); + pixelsOperation.setIntPara3(intPara3); + target = pixelsOperation.operate(); break; - case Posterizing: - target = ImageEffectTools.posterizing(ImageConvertTools.removeAlpha(source), intValue); + case Quantization: + int channelSize = (int) Math.round(Math.pow(intPara1, 1.0 / 3.0)); + ImageQuantization quantization = new ImageQuantization(ImageConvert.removeAlpha(source), + quantizationAlgorithm, channelSize); + quantization.setIsDithering(valueCheck.isSelected()); + target = quantization.operate(); break; case Gray: - target = ImageGrayTools.color2Gray(source); + target = ImageGray.byteGray(source); break; case BlackOrWhite: - if (bwValue < 0) { - target = ImageGrayTools.color2Binary(source); - } else { - target = ImageGrayTools.color2BinaryWithPercentage(source, bwValue); + ImageBinary imageBinary; + switch (intPara1) { + case 2: + imageBinary = new ImageBinary(source, -1); + break; + case 3: + imageBinary = new ImageBinary(source, intPara2); + break; + default: + int t = ImageBinary.calculateThreshold(source); + imageBinary = new ImageBinary(source, t); + break; } + imageBinary.setIsDithering(valueCheck.isSelected()); + target = imageBinary.operate(); break; case Sepia: - target = ImageEffectTools.sepiaImage(source, bwValue); + pixelsOperation = new PixelsOperation(source, effectType); + pixelsOperation.setIntPara1(intPara1); + target = pixelsOperation.operate(); break; default: break; diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchReplaceColorController.java b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchReplaceColorController.java index d8f24405a..cfce44a8c 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchReplaceColorController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchReplaceColorController.java @@ -17,12 +17,13 @@ import javafx.scene.layout.HBox; import javafx.scene.paint.Color; import javafx.scene.text.Font; -import static mara.mybox.objects.AppVaribles.logger; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.fxml.FxmlImageTools; +import static mara.mybox.value.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.getMessage; import mara.mybox.fxml.FxmlTools; import static mara.mybox.fxml.FxmlTools.badStyle; -import mara.mybox.image.ImageReplaceColorTools; +import mara.mybox.image.ImageColor; +import mara.mybox.image.ImageScope; +import mara.mybox.image.PixelsOperation; /** * @Author Mara @@ -184,10 +185,25 @@ private void blackForNew(ActionEvent event) { @Override protected BufferedImage handleImage(BufferedImage source) { - BufferedImage target = ImageReplaceColorTools.replaceColor(source, - FxmlImageTools.colorConvert(oldColorPicker.getValue()), - FxmlImageTools.colorConvert(newColorPicker.getValue()), - distance, isColor, excludeCheck.isSelected()); + ImageScope scope = new ImageScope(); + if (isColor) { + scope.setColorScopeType(ImageScope.ColorScopeType.Color); + scope.setColorDistance(distance); + } else { + scope.setColorScopeType(ImageScope.ColorScopeType.Hue); + scope.setHsbDistance(distance / 360.0f); + } + scope.setColorExcluded(excludeCheck.isSelected()); + PixelsOperation pixelsOperation = new PixelsOperation(source, scope, + PixelsOperation.OperationType.ReplaceColor); + pixelsOperation.setColorPara1(ImageColor.converColor(oldColorPicker.getValue())); + pixelsOperation.setColorPara2(ImageColor.converColor(newColorPicker.getValue())); + BufferedImage target = pixelsOperation.operate(); + +// BufferedImage target = ImageReplaceColorTools.replaceColor(source, +// FxmlManufactureTools.colorConvert(oldColorPicker.getValue()), +// FxmlManufactureTools.colorConvert(newColorPicker.getValue()), +// distance, isColor, excludeCheck.isSelected()); return target; } diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchShadowController.java b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchShadowController.java index 1df90718b..294950f35 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchShadowController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchShadowController.java @@ -15,10 +15,10 @@ import javafx.scene.control.Tooltip; import javafx.scene.paint.Color; import javafx.scene.text.Font; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.image.ImageConvertTools; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.fxml.FxmlImageTools; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.image.ImageConvert; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.fxml.image.ImageTools; import mara.mybox.fxml.FxmlTools; import static mara.mybox.fxml.FxmlTools.badStyle; @@ -180,7 +180,7 @@ protected BufferedImage handleImage(BufferedImage source) { value = source.getWidth() * percent / 100; } Color color = shadowColorPicker.getValue(); - BufferedImage target = ImageConvertTools.addShadow(source, value, FxmlImageTools.colorConvert(color)); + BufferedImage target = ImageConvert.addShadow(source, value, ImageTools.colorConvert(color)); return target; } catch (Exception e) { diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchSizeController.java b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchSizeController.java index f4ae2cafd..ef929e1ac 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchSizeController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchSizeController.java @@ -16,10 +16,10 @@ import javafx.scene.layout.Pane; import javafx.stage.Modality; import javafx.stage.Stage; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.image.ImageConvertTools; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.CommonValues; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.image.ImageConvert; +import mara.mybox.value.AppVaribles; +import mara.mybox.value.CommonValues; import static mara.mybox.fxml.FxmlTools.badStyle; /** @@ -272,16 +272,16 @@ protected BufferedImage handleImage(BufferedImage source) { try { BufferedImage target = null; if (sizeType == SizeType.Scale) { - target = ImageConvertTools.scaleImage(source, scale); + target = ImageConvert.scaleImage(source, scale); } else if (sizeType == SizeType.Width) { - target = ImageConvertTools.scaleImageWidthKeep(source, keepWidth); + target = ImageConvert.scaleImageWidthKeep(source, keepWidth); } else if (sizeType == SizeType.Height) { - target = ImageConvertTools.scaleImageHeightKeep(source, keepHeight); + target = ImageConvert.scaleImageHeightKeep(source, keepHeight); } else if (sizeType == SizeType.Custom) { - target = ImageConvertTools.scaleImage(source, customWidth, customHeight); + target = ImageConvert.scaleImage(source, customWidth, customHeight); } return target; diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchTextController.java b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchTextController.java index 9d14eb5e7..8ebe41926 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchTextController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchTextController.java @@ -20,11 +20,11 @@ import javafx.scene.text.FontPosture; import javafx.scene.text.FontWeight; import javafx.scene.text.Text; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.image.ImageConvertTools; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.fxml.FxmlImageTools; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.image.ImageConvert; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.fxml.image.ImageTools; import static mara.mybox.fxml.FxmlTools.badStyle; /** @@ -323,7 +323,7 @@ protected void makeMoreParameters() { FxFont = Font.font(fontFamily, FontWeight.NORMAL, FontPosture.REGULAR, waterSize); } - color = FxmlImageTools.colorConvert(waterColorPicker.getValue()); + color = ImageTools.colorConvert(waterColorPicker.getValue()); final String msg = waterInput.getText().trim(); final Text text = new Text(msg); @@ -368,7 +368,7 @@ protected BufferedImage handleImage(BufferedImage source) { break; } - BufferedImage target = ImageConvertTools.addText(source, + BufferedImage target = ImageConvert.addText(source, waterInput.getText().trim(), font, color, x, y, waterTransparent, waterShadow, waterAngle, false); diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchTransformController.java b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchTransformController.java index 8709c2ca9..8416d413f 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchTransformController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBatchTransformController.java @@ -12,10 +12,10 @@ import javafx.scene.control.Slider; import javafx.scene.control.Toggle; import javafx.scene.control.ToggleGroup; -import static mara.mybox.objects.AppVaribles.logger; -import static mara.mybox.objects.AppVaribles.getMessage; +import static mara.mybox.value.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.getMessage; import static mara.mybox.fxml.FxmlTools.badStyle; -import mara.mybox.image.ImageTransformTools; +import mara.mybox.image.ImageTransform; /** * @Author Mara @@ -167,16 +167,16 @@ protected BufferedImage handleImage(BufferedImage source) { try { BufferedImage target = null; if (transformType == TransformType.Shear) { - target = ImageTransformTools.shearImage(source, shearX, 0); + target = ImageTransform.shearImage(source, shearX, 0); } else if (transformType == TransformType.VerticalMirror) { - target = ImageTransformTools.verticalMirrorImage(source); + target = ImageTransform.verticalMirrorImage(source); } else if (transformType == TransformType.HorizontalMirror) { - target = ImageTransformTools.horizontalMirrorImage(source); + target = ImageTransform.horizontalMirrorImage(source); } else if (transformType == TransformType.Rotate) { - target = ImageTransformTools.rotateImage(source, rotateAngle); + target = ImageTransform.rotateImage(source, rotateAngle); } return target; diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBrowseController.java b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBrowseController.java index d1b064147..18a0eb9dc 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBrowseController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureBrowseController.java @@ -5,10 +5,11 @@ import javafx.fxml.FXML; import javafx.scene.control.RadioButton; import javafx.scene.control.Toggle; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; +import javafx.scene.control.ToolBar; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.AppVaribles; import mara.mybox.fxml.FxmlTools; +import static mara.mybox.value.AppVaribles.getMessage; /** * @Author Mara @@ -20,6 +21,9 @@ public class ImageManufactureBrowseController extends ImageManufactureController final protected String ImageSortTypeKey; + @FXML + protected ToolBar navBar; + public ImageManufactureBrowseController() { ImageSortTypeKey = "ImageSortType"; } @@ -44,8 +48,10 @@ protected void initInterface() { isSettingValues = true; - navBar.setDisable(false); - checkImageNevigator(); + if (sourceFile != null && navBox != null) { + navBox.setDisable(false); + checkImageNevigator(); + } isSettingValues = false; } catch (Exception e) { @@ -79,6 +85,7 @@ public void nextAction() { return; } if (nextFile != null) { + setImageChanged(false); loadImage(nextFile.getAbsoluteFile(), false); } } @@ -90,6 +97,7 @@ public void previousAction() { return; } if (previousFile != null) { + setImageChanged(false); loadImage(previousFile.getAbsoluteFile(), false); } } diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureColorController.java b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureColorController.java index 856fba7af..eead11533 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureColorController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureColorController.java @@ -20,15 +20,15 @@ import javafx.scene.paint.Color; import javafx.scene.text.Font; import javafx.stage.Modality; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.fxml.FxmlAdjustColorTools; -import mara.mybox.fxml.FxmlAdjustColorTools.ColorActionType; -import mara.mybox.fxml.FxmlAdjustColorTools.ColorObjectType; +import static mara.mybox.value.AppVaribles.logger; import mara.mybox.fxml.FxmlTools; -import mara.mybox.objects.CommonValues; +import mara.mybox.value.CommonValues; import static mara.mybox.fxml.FxmlTools.badStyle; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.ImageScope; +import mara.mybox.fxml.image.PixelsOperation; +import mara.mybox.image.ImageColor; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.image.PixelsOperation.ColorActionType; +import mara.mybox.image.PixelsOperation.OperationType; /** * @Author Mara @@ -39,7 +39,7 @@ public class ImageManufactureColorController extends ImageManufactureController { protected int colorValue; - private ColorObjectType colorOperationType; + private OperationType colorOperationType; private ColorActionType colorActionType; @FXML @@ -98,17 +98,17 @@ public void changed(ObservableValue observable, colorPicker.setValue(Color.TRANSPARENT); - Tooltip tips = new Tooltip("CTRL+a"); + Tooltip tips = new Tooltip("CTRL+q"); tips.setFont(new Font(16)); - FxmlTools.quickTooltip(increaseButton, tips); + FxmlTools.quickTooltip(setButton, tips); - tips = new Tooltip("CTRL+q"); + tips = new Tooltip("CTRL+w"); tips.setFont(new Font(16)); - FxmlTools.quickTooltip(decreaseButton, tips); + FxmlTools.quickTooltip(increaseButton, tips); - tips = new Tooltip("CTRL+w"); + tips = new Tooltip("CTRL+e"); tips.setFont(new Font(16)); - FxmlTools.quickTooltip(setButton, tips); + FxmlTools.quickTooltip(decreaseButton, tips); colorPicker.setValue(Color.TRANSPARENT); @@ -131,7 +131,8 @@ protected void initInterface() { checkColorInput(); isSettingValues = true; - if (CommonValues.NoAlphaImages.contains(values.getImageInfo().getImageFormat())) { + if (values.getImageInfo() != null + && CommonValues.NoAlphaImages.contains(values.getImageInfo().getImageFormat())) { opacityRadio.setDisable(true); // opacityRadio.setPrefWidth(0); } else { @@ -154,12 +155,10 @@ private void checkColorOperationType() { increaseButton.setDisable(false); filterButton.setDisable(false); invertButton.setDisable(false); - if (scope != null) { - scope.setOperationType(ImageScope.OperationType.Color); - } + isSettingColor = false; RadioButton selected = (RadioButton) colorGroup.getSelectedToggle(); if (getMessage("Brightness").equals(selected.getText())) { - colorOperationType = ColorObjectType.Brightness; + colorOperationType = OperationType.Brightness; colorSlider.setMax(100); colorSlider.setMin(1); colorSlider.setBlockIncrement(1); @@ -170,7 +169,7 @@ private void checkColorOperationType() { filterButton.setDisable(true); invertButton.setDisable(true); } else if (getMessage("Saturation").equals(selected.getText())) { - colorOperationType = ColorObjectType.Sauration; + colorOperationType = OperationType.Sauration; colorSlider.setMax(100); colorSlider.setMin(1); colorSlider.setBlockIncrement(1); @@ -181,7 +180,7 @@ private void checkColorOperationType() { filterButton.setDisable(true); invertButton.setDisable(true); } else if (getMessage("Hue").equals(selected.getText())) { - colorOperationType = ColorObjectType.Hue; + colorOperationType = OperationType.Hue; colorSlider.setMax(359); colorSlider.setMin(1); colorSlider.setBlockIncrement(1); @@ -192,7 +191,7 @@ private void checkColorOperationType() { filterButton.setDisable(true); invertButton.setDisable(true); } else if (getMessage("Red").equals(selected.getText())) { - colorOperationType = ColorObjectType.Red; + colorOperationType = OperationType.Red; colorSlider.setMax(255); colorSlider.setMin(1); colorSlider.setBlockIncrement(1); @@ -201,7 +200,7 @@ private void checkColorOperationType() { colorInput.setText("50"); } } else if (getMessage("Green").equals(selected.getText())) { - colorOperationType = ColorObjectType.Green; + colorOperationType = OperationType.Green; colorSlider.setMax(255); colorSlider.setMin(1); colorSlider.setBlockIncrement(1); @@ -210,7 +209,7 @@ private void checkColorOperationType() { colorInput.setText("50"); } } else if (getMessage("Blue").equals(selected.getText())) { - colorOperationType = ColorObjectType.Blue; + colorOperationType = OperationType.Blue; colorSlider.setMax(255); colorSlider.setMin(1); colorSlider.setBlockIncrement(1); @@ -219,7 +218,7 @@ private void checkColorOperationType() { colorInput.setText("50"); } } else if (getMessage("Yellow").equals(selected.getText())) { - colorOperationType = ColorObjectType.Yellow; + colorOperationType = OperationType.Yellow; colorSlider.setMax(255); colorSlider.setMin(1); colorSlider.setBlockIncrement(1); @@ -228,7 +227,7 @@ private void checkColorOperationType() { colorInput.setText("50"); } } else if (getMessage("Cyan").equals(selected.getText())) { - colorOperationType = ColorObjectType.Cyan; + colorOperationType = OperationType.Cyan; colorSlider.setMax(255); colorSlider.setMin(1); colorSlider.setBlockIncrement(1); @@ -237,7 +236,7 @@ private void checkColorOperationType() { colorInput.setText("50"); } } else if (getMessage("Magenta").equals(selected.getText())) { - colorOperationType = ColorObjectType.Magenta; + colorOperationType = OperationType.Magenta; colorSlider.setMax(255); colorSlider.setMin(1); colorSlider.setBlockIncrement(1); @@ -246,7 +245,7 @@ private void checkColorOperationType() { colorInput.setText("50"); } } else if (getMessage("RGB").equals(selected.getText())) { - colorOperationType = ColorObjectType.RGB; + colorOperationType = OperationType.RGB; colorSlider.setMax(255); colorSlider.setMin(1); colorSlider.setBlockIncrement(1); @@ -257,7 +256,7 @@ private void checkColorOperationType() { filterButton.setDisable(true); setButton.setDisable(true); } else if (getMessage("Opacity").equals(selected.getText())) { - colorOperationType = ColorObjectType.Opacity; + colorOperationType = OperationType.Opacity; colorSlider.setMax(100); colorSlider.setMin(0); colorSlider.setBlockIncrement(1); @@ -268,16 +267,14 @@ private void checkColorOperationType() { filterButton.setDisable(true); invertButton.setDisable(true); } else if (getMessage("Color").equals(selected.getText())) { - if (scope != null) { - scope.setOperationType(ImageScope.OperationType.ReplaceColor); - } - colorOperationType = ColorObjectType.Color; + colorOperationType = OperationType.Color; decreaseButton.setDisable(true); increaseButton.setDisable(true); filterButton.setDisable(true); invertButton.setDisable(true); colorHBox.setDisable(false); sliderHBox.setDisable(true); + isSettingColor = true; } if (scope != null) { showLabels(); @@ -331,23 +328,29 @@ public void invertAction() { @Override protected void keyEventsHandler(KeyEvent event) { super.keyEventsHandler(event); - String key = event.getText(); - if (key == null || key.isEmpty()) { - return; - } if (event.isControlDown()) { + String key = event.getText(); + if (key == null || key.isEmpty()) { + return; + } switch (key) { - case "a": - case "A": - increaseAction(); - break; case "q": case "Q": - decreaseAction(); + if (setButton != null && !setButton.isDisabled()) { + setAction(); + } break; case "w": case "W": - setAction(); + if (increaseButton != null && !increaseButton.isDisabled()) { + increaseAction(); + } + break; + case "e": + case "E": + if (decreaseButton != null && !decreaseButton.isDisabled()) { + decreaseAction(); + } break; } } @@ -360,12 +363,15 @@ private void applyChange() { task = new Task() { @Override protected Void call() throws Exception { - double change = colorValue; + PixelsOperation pixelsOperation = new PixelsOperation(values.getCurrentImage(), scope, + colorOperationType, colorActionType); switch (colorOperationType) { + case Hue: + pixelsOperation.setFloatPara1(colorValue / 360.0f); + break; case Brightness: case Sauration: - case Opacity: - change = change / 100.0f; + pixelsOperation.setFloatPara1(colorValue / 100.0f); break; case Red: case Green: @@ -374,11 +380,16 @@ protected Void call() throws Exception { case Cyan: case Magenta: case RGB: - change = change / 255.0; + pixelsOperation.setIntPara1(colorValue); + break; + case Opacity: + pixelsOperation.setIntPara1(colorValue * 255 / 100); + break; + case Color: + pixelsOperation.setColorPara1(ImageColor.converColor(colorPicker.getValue())); break; } - final Image newImage = FxmlAdjustColorTools.ajustColor(values.getCurrentImage(), - colorOperationType, colorActionType, change, colorPicker.getValue(), scope); + final Image newImage = pixelsOperation.operateFxImage(); if (task.isCancelled()) { return null; } diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureController.java b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureController.java index 9f7e0adf4..f47356981 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureController.java @@ -29,14 +29,10 @@ import javafx.scene.control.Label; import javafx.scene.control.ListCell; import javafx.scene.control.ListView; -import javafx.scene.control.RadioButton; import javafx.scene.control.ScrollPane; -import javafx.scene.control.SplitPane; import javafx.scene.control.Tab; import javafx.scene.control.TabPane; import javafx.scene.control.TextField; -import javafx.scene.control.Toggle; -import javafx.scene.control.ToggleGroup; import javafx.scene.control.ToolBar; import javafx.scene.control.Tooltip; import javafx.scene.image.Image; @@ -47,6 +43,7 @@ import javafx.scene.input.MouseEvent; import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; +import javafx.scene.layout.Region; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; import javafx.scene.shape.Rectangle; @@ -55,27 +52,29 @@ import javafx.stage.Modality; import javafx.util.Callback; import javax.imageio.ImageIO; -import static mara.mybox.objects.AppVaribles.logger; import mara.mybox.db.TableImageHistory; import mara.mybox.db.TableImageInit; -import mara.mybox.imagefile.ImageFileReaders; -import mara.mybox.imagefile.ImageFileWriters; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.ImageHistory; -import mara.mybox.objects.ImageManufactureValues; -import mara.mybox.objects.ImageScope; +import mara.mybox.image.file.ImageFileReaders; +import mara.mybox.image.file.ImageFileWriters; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.value.CommonValues; +import mara.mybox.data.ImageHistory; +import mara.mybox.data.ImageManufactureValues; +import mara.mybox.image.ImageScope; import mara.mybox.tools.DateTools; import mara.mybox.tools.FileTools; import mara.mybox.fxml.FxmlTools; -import mara.mybox.fxml.FxmlImageTools; -import mara.mybox.fxml.FxmlScopeTools; +import mara.mybox.fxml.image.ImageTools; +import mara.mybox.fxml.image.FxmlScopeTools; import static mara.mybox.fxml.FxmlTools.badStyle; -import mara.mybox.objects.ImageScope.ColorScopeType; -import mara.mybox.objects.ImageScope.OperationType; -import mara.mybox.objects.ImageScope.ScopeType; -import mara.mybox.objects.IntRectangle; +import mara.mybox.fxml.image.PixelsOperation; +import mara.mybox.image.ImageColor; +import mara.mybox.image.ImageScope.ColorScopeType; +import mara.mybox.image.ImageScope.ScopeType; +import mara.mybox.image.PixelsOperation.OperationType; +import mara.mybox.data.IntRectangle; +import static mara.mybox.value.AppVaribles.logger; /** * @Author Mara @@ -89,15 +88,12 @@ public abstract class ImageManufactureController extends ImageViewerController { protected ImageView refView, scopeView; protected Label refLabel; protected VBox refBox, scopeBox; - protected ImageManufactureValues values; - protected boolean isSettingValues, isSwitchingTab; - + protected boolean isSwitchingTab, isSettingColor; protected String initTab; protected int stageWidth, stageHeight; protected String imageHistoriesPath; protected List imageHistories; - protected ImageScope scope; protected TextField scopeLeftXInput, scopeLeftYInput, scopeRightXInput, scopeRightYInput; @@ -134,31 +130,27 @@ protected class ImageManufactureParameters { protected ToolBar fileBar, hotBar; @FXML protected Tab fileTab, viewTab, colorTab, textTab, coverTab, cropTab, - arcTab, shadowTab, effectsTab, convolutionTab, sizeTab, refTab, + arcTab, shadowTab, effectsTab, sizeTab, refTab, browseTab, transformTab, marginsTab; @FXML - protected Label tipsLabel, promptLabel, imageLabel; + protected Label promptLabel, imageLabel; @FXML - protected Button selectRefButton, saveButton, recoverButton, undoButton, redoButton; + protected Button selectRefButton, recoverButton, undoButton, redoButton, popButton, refButton; @FXML protected CheckBox showRefCheck, showScopeCheck, saveCheck; @FXML - protected SplitPane splitPane; - @FXML protected TabPane tabPane; @FXML protected HBox hotBox, imageLabelBox; @FXML protected VBox imageBox; @FXML - protected ComboBox hisBox; - @FXML - protected ToggleGroup scopeGroup; + protected ComboBox hisBox, scopeListBox; @FXML protected ColorPicker colorPicker; public ImageManufactureController() { - sourcePathKey = "ImageSourcePathKey"; + TipsLabelKey = "ImageManufactureTips"; } @@ -166,12 +158,12 @@ protected void initCommon() { try { values = new ImageManufactureValues(); values.setRefSync(true); + isSettingColor = false; browseTab.setDisable(true); viewTab.setDisable(true); colorTab.setDisable(true); effectsTab.setDisable(true); - convolutionTab.setDisable(true); sizeTab.setDisable(true); refTab.setDisable(true); transformTab.setDisable(true); @@ -196,11 +188,7 @@ public void changed(ObservableValue observable, } }); - Tooltip tips = new Tooltip(getMessage("ImageManufactureTips")); - tips.setFont(new Font(16)); - FxmlTools.quickTooltip(tipsLabel, tips); - - tips = new Tooltip(getMessage("ImageRefTips")); + Tooltip tips = new Tooltip(getMessage("ImageRefTips")); tips.setFont(new Font(16)); FxmlTools.setComments(showRefCheck, tips); showRefCheck.selectedProperty().addListener(new ChangeListener() { @@ -221,7 +209,7 @@ public void changed(ObservableValue ov, Number oldValue, Number newValue) { return; } if (getMessage("SettingsDot").equals(hisBox.getItems().get(index))) { - BaseController c = openStage(CommonValues.SettingsFxml, true); + BaseController c = openStage(CommonValues.SettingsFxml, false); c.setParentController(getMyController()); c.setParentFxml(getMyFxml()); return; @@ -258,27 +246,19 @@ public void changed(ObservableValue ov, Number oldValue, Number newValue) { tips.setFont(new Font(16)); FxmlTools.quickTooltip(undoButton, tips); - tips = new Tooltip("CTRL+1"); - tips.setFont(new Font(16)); - FxmlTools.quickTooltip(oButton, tips); - - tips = new Tooltip("CTRL+2"); - tips.setFont(new Font(16)); - FxmlTools.quickTooltip(wButton, tips); - - tips = new Tooltip("CTRL+3"); + tips = new Tooltip("CTRL+h"); tips.setFont(new Font(16)); - FxmlTools.quickTooltip(inButton, tips); + FxmlTools.quickTooltip(hisBox, tips); - tips = new Tooltip("CTRL+4"); + tips = new Tooltip("CTRL+f"); tips.setFont(new Font(16)); - FxmlTools.quickTooltip(outButton, tips); + FxmlTools.quickTooltip(refButton, tips); - tips = new Tooltip("CTRL+h"); + tips = new Tooltip("CTRL+p"); tips.setFont(new Font(16)); - FxmlTools.quickTooltip(hisBox, tips); + FxmlTools.quickTooltip(popButton, tips); - if (showScopeCheck != null && scopeGroup != null) { + if (showScopeCheck != null && scopeListBox != null) { tips = new Tooltip(getMessage("ShowScopeComments")); tips.setFont(new Font(16)); FxmlTools.setComments(showScopeCheck, tips); @@ -313,7 +293,6 @@ protected void initInterface() { cropTab.setDisable(false); colorTab.setDisable(false); - convolutionTab.setDisable(false); effectsTab.setDisable(false); arcTab.setDisable(false); shadowTab.setDisable(false); @@ -374,6 +353,8 @@ public void changed(ObservableValue observableValue, isSettingValues = false; + imageData = values.getImageData(); + } catch (Exception e) { logger.debug(e.toString()); } @@ -383,13 +364,17 @@ public void changed(ObservableValue observableValue, protected void initScopeBar() { try { - scopeGroup.selectedToggleProperty().addListener(new ChangeListener() { + List scopeList = Arrays.asList(getMessage("All"), + getMessage("Rectangle"), getMessage("Circle"), getMessage("Matting"), getMessage("ColorMatching"), + getMessage("RectangleColor"), getMessage("CircleColor")); + scopeListBox.getItems().addAll(scopeList); + scopeListBox.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener() { @Override - public void changed(ObservableValue ov, - Toggle old_toggle, Toggle new_toggle) { + public void changed(ObservableValue ov, Number oldValue, Number newValue) { checkScopeType(); } }); + scopeListBox.getSelectionModel().select(0); } catch (Exception e) { logger.error(e.toString()); @@ -406,30 +391,30 @@ protected void checkScopeType() { scope.clearColors(); scope.clearPoints(); - RadioButton selected = (RadioButton) scopeGroup.getSelectedToggle(); - if (AppVaribles.getMessage("All").equals(selected.getText())) { + String selected = scopeListBox.getSelectionModel().getSelectedItem(); + if (AppVaribles.getMessage("All").equals(selected)) { scope.setScopeType(ImageScope.ScopeType.All); showScopeCheck.setDisable(true); hideScopePane(); } else { - if (AppVaribles.getMessage("Matting").equals(selected.getText())) { + if (AppVaribles.getMessage("Matting").equals(selected)) { scope.setScopeType(ImageScope.ScopeType.Matting); - } else if (getMessage("Rectangle").equals(selected.getText())) { + } else if (getMessage("Rectangle").equals(selected)) { scope.setScopeType(ImageScope.ScopeType.Rectangle); - } else if (getMessage("Circle").equals(selected.getText())) { + } else if (getMessage("Circle").equals(selected)) { scope.setScopeType(ImageScope.ScopeType.Circle); - } else if (getMessage("ColorMatching").equals(selected.getText())) { + } else if (getMessage("ColorMatching").equals(selected)) { scope.setScopeType(ImageScope.ScopeType.Color); - } else if (getMessage("RectangleColor").equals(selected.getText())) { + } else if (getMessage("RectangleColor").equals(selected)) { scope.setScopeType(ImageScope.ScopeType.RectangleColor); - } else if (getMessage("CircleColor").equals(selected.getText())) { + } else if (getMessage("CircleColor").equals(selected)) { scope.setScopeType(ImageScope.ScopeType.CircleColor); } @@ -499,7 +484,7 @@ protected boolean checkDistanceValue() { case Hue: if (distance >= 0 && distance <= 360) { scopeDistanceInput.setStyle(null); - scope.setHueDistance(distance); + scope.setHsbDistance(distance / 360.0f); } else { scopeDistanceInput.setStyle(badStyle); valid = false; @@ -509,7 +494,7 @@ protected boolean checkDistanceValue() { case Saturation: if (distance >= 0 && distance <= 100) { scopeDistanceInput.setStyle(null); - scope.setColorDistance(distance / 100.0); + scope.setHsbDistance(distance / 100.0f); } else { scopeDistanceInput.setStyle(badStyle); valid = false; @@ -518,7 +503,7 @@ protected boolean checkDistanceValue() { default: if (distance >= 0 && distance <= 255) { scopeDistanceInput.setStyle(null); - scope.setColorDistance(distance / 255.0); + scope.setColorDistance(distance); } else { scopeDistanceInput.setStyle(badStyle); valid = false; @@ -710,7 +695,8 @@ protected Void call() throws Exception { if (task.isCancelled()) { return null; } - Image scopedImage = FxmlScopeTools.scopeImage(values.getCurrentImage(), scope); + PixelsOperation pixelsOperation = new PixelsOperation(values.getCurrentImage(), scope, OperationType.Scope); + final Image scopedImage = pixelsOperation.operateFxImage(); if (task.isCancelled()) { return null; } @@ -759,7 +745,8 @@ protected Void call() throws Exception { if (task.isCancelled()) { return null; } - Image scopedImage = FxmlScopeTools.scopeImage(values.getCurrentImage(), scope); + PixelsOperation pixelsOperation = new PixelsOperation(values.getCurrentImage(), scope, OperationType.Scope); + final Image scopedImage = pixelsOperation.operateFxImage(); if (task.isCancelled()) { return null; } @@ -798,7 +785,8 @@ protected void indicateMatting() { @Override protected Void call() throws Exception { try { - final Image scopeImage = FxmlScopeTools.scopeMatting(values.getCurrentImage(), scope); + PixelsOperation pixelsOperation = new PixelsOperation(values.getCurrentImage(), scope, OperationType.Scope); + final Image scopeImage = pixelsOperation.operateFxImage(); if (task.isCancelled()) { return null; } @@ -831,7 +819,8 @@ protected void indicateColor() { @Override protected Void call() throws Exception { try { - final Image scopeImage = FxmlScopeTools.scopeImage(values.getCurrentImage(), scope); + PixelsOperation pixelsOperation = new PixelsOperation(values.getCurrentImage(), scope, OperationType.Scope); + final Image scopeImage = pixelsOperation.operateFxImage(); if (task.isCancelled()) { return null; } @@ -856,6 +845,81 @@ public void run() { thread.start(); } + @FXML + @Override + protected void selectSourceFile(ActionEvent event) { + if (values == null || values.getCurrentImage() != null && values.isImageChanged()) { + if (!checkSavingBeforeExit()) { + return; + } + } + super.selectSourceFile(event); + } + + @Override + public void afterImageLoaded() { + try { + super.afterImageLoaded(); + + if (imageInformation != null && imageInformation.isIsSampled()) { + hotBar.setDisable(false); + showRefCheck.setDisable(true); + hisBox.setDisable(true); + undoButton.setDisable(true); + redoButton.setDisable(true); + recoverButton.setDisable(true); + saveButton.setDisable(true); + + browseTab.setDisable(true); + viewTab.setDisable(true); + colorTab.setDisable(true); + effectsTab.setDisable(true); + sizeTab.setDisable(true); + refTab.setDisable(true); + transformTab.setDisable(true); + textTab.setDisable(true); + coverTab.setDisable(true); + arcTab.setDisable(true); + shadowTab.setDisable(true); + marginsTab.setDisable(true); + cropTab.setDisable(true); + + } + + isSettingValues = true; + values.setSourceFile(sourceFile); + values.setImage(image); + values.setImageInfo(imageInformation); + values.setCurrentImage(image); + isSettingValues = false; + + if (image == null + || (imageInformation != null && imageInformation.isIsSampled())) { + return; + } + + isSettingValues = true; + values.setRefImage(image); + values.setRefInfo(imageInformation); + setImageChanged(false); + values.setScope(new ImageScope(image)); + scope = values.getScope(); + + recordImageHistory(ImageOperationType.Load, image); + + imageData = values.getImageData(); + if (initTab != null) { + switchTab(initTab); + } else { + initInterface(); + } + isSettingValues = false; + + } catch (Exception e) { + logger.debug(e.toString()); + } + } + public void setImage(final File file) { task = new Task() { @Override @@ -986,12 +1050,12 @@ protected void loadReferenceImage() { values.setRefImage(image); values.setRefInfo(values.getImageInfo()); refView.setImage(image); - if (scrollPane.getHeight() < values.getImageInfo().getWidth()) { + if (scrollPane.getHeight() < (int) values.getImage().getWidth()) { refView.setFitWidth(scrollPane.getWidth() - 1); refView.setFitHeight(scrollPane.getHeight() - 5); // use attributes of scrollPane but not refPane } else { - refView.setFitWidth(values.getImageInfo().getWidth()); - refView.setFitHeight(values.getImageInfo().getHeight()); + refView.setFitWidth((int) values.getImage().getWidth()); + refView.setFitHeight((int) values.getImage().getHeight()); } return; } @@ -1040,6 +1104,8 @@ protected void setImageChanged(boolean imageChanged) { undoButton.setDisable(false); redoButton.setDisable(true); + loadData(); + } else { saveButton.setDisable(true); recoverButton.setDisable(true); @@ -1140,7 +1206,7 @@ protected void recordImageHistory(final int updateType, final Image newImage) { @Override protected Void call() throws Exception { try { - final BufferedImage bufferedImage = FxmlImageTools.getBufferedImage(newImage); + final BufferedImage bufferedImage = ImageTools.getBufferedImage(newImage); String filename = imageHistoriesPath + File.separator + FileTools.getFilePrefix(values.getSourceFile().getName()) + "_" + (new Date().getTime()) + "_" + updateType @@ -1197,42 +1263,11 @@ protected boolean loadImageHistory(final int index) { protected void switchTab(Tab newTab) { - String tabName = null; - if (fileTab.equals(newTab)) { - tabName = "file"; - } else if (sizeTab.equals(newTab)) { - tabName = "size"; - } else if (cropTab.equals(newTab)) { - tabName = "crop"; - } else if (convolutionTab.equals(newTab)) { - tabName = "convolution"; - } else if (effectsTab.equals(newTab)) { - tabName = "effects"; - } else if (colorTab.equals(newTab)) { - tabName = "color"; - } else if (textTab.equals(newTab)) { - tabName = "text"; - } else if (coverTab.equals(newTab)) { - tabName = "cover"; - } else if (arcTab.equals(newTab)) { - tabName = "arc"; - } else if (shadowTab.equals(newTab)) { - tabName = "shadow"; - } else if (transformTab.equals(newTab)) { - tabName = "transform"; - } else if (marginsTab.equals(newTab)) { - tabName = "margins"; - } else if (viewTab.equals(newTab)) { - tabName = "view"; - } else if (refTab.equals(newTab)) { - tabName = "ref"; - } else if (browseTab.equals(newTab)) { - tabName = "browse"; - } + String tabName = findTabName(newTab); switchTab(tabName); } - protected void switchTab(String tabName) { + public void switchTab(String tabName) { try { isSwitchingTab = true; String fxml = null; @@ -1249,9 +1284,6 @@ protected void switchTab(String tabName) { case "color": fxml = CommonValues.ImageManufactureColorFxml; break; - case "convolution": - fxml = CommonValues.ImageManufactureConvolutionFxml; - break; case "effects": fxml = CommonValues.ImageManufactureEffectsFxml; break; @@ -1285,10 +1317,12 @@ protected void switchTab(String tabName) { } if (fxml != null) { +// values.setCurrentImage(imageView.getImage()); values.setStageWidth(stageWidth); values.setStageHeight(stageHeight); values.setImageViewWidth((int) imageView.getFitWidth()); values.setImageViewHeight((int) imageView.getFitHeight()); + values.setImageData(imageData); ImageManufactureController controller = (ImageManufactureController) reloadStage(fxml, AppVaribles.getMessage("ImageManufacture")); controller.setValues(values); @@ -1296,86 +1330,113 @@ protected void switchTab(String tabName) { controller.xZoomStep = xZoomStep; controller.yZoomStep = yZoomStep; controller.initInterface(); + controller.loadData(imageData); } + isSwitchingTab = false; } catch (Exception e) { logger.error(e.toString()); } } - public void setTab(String tab) { + public void setTab(String tabName) { try { + Tab tab = findTab(tabName); if (tab == null) { return; } isSettingValues = true; - switch (tab) { - case "file": - tabPane.getSelectionModel().select(fileTab); - break; - case "size": - tabPane.getSelectionModel().select(sizeTab); - break; - case "crop": - tabPane.getSelectionModel().select(cropTab); - break; - case "color": - tabPane.getSelectionModel().select(colorTab); - break; - case "convolution": - tabPane.getSelectionModel().select(convolutionTab); - break; - case "effects": - tabPane.getSelectionModel().select(effectsTab); - break; - case "text": - tabPane.getSelectionModel().select(textTab); - break; - case "cover": - tabPane.getSelectionModel().select(coverTab); - break; - case "arc": - tabPane.getSelectionModel().select(arcTab); - break; - case "shadow": - tabPane.getSelectionModel().select(shadowTab); - break; - case "transform": - tabPane.getSelectionModel().select(transformTab); - break; - case "margins": - tabPane.getSelectionModel().select(marginsTab); - break; - case "view": - tabPane.getSelectionModel().select(viewTab); - break; - case "ref": - tabPane.getSelectionModel().select(refTab); - break; - case "browse": - tabPane.getSelectionModel().select(browseTab); - break; - } + tabPane.getSelectionModel().select(tab); isSettingValues = false; } catch (Exception e) { logger.debug(e.toString()); } } + protected String findTabName(Tab tab) { + String tabName = null; + if (fileTab.equals(tab)) { + tabName = "file"; + } else if (sizeTab.equals(tab)) { + tabName = "size"; + } else if (cropTab.equals(tab)) { + tabName = "crop"; + } else if (effectsTab.equals(tab)) { + tabName = "effects"; + } else if (colorTab.equals(tab)) { + tabName = "color"; + } else if (textTab.equals(tab)) { + tabName = "text"; + } else if (coverTab.equals(tab)) { + tabName = "cover"; + } else if (arcTab.equals(tab)) { + tabName = "arc"; + } else if (shadowTab.equals(tab)) { + tabName = "shadow"; + } else if (transformTab.equals(tab)) { + tabName = "transform"; + } else if (marginsTab.equals(tab)) { + tabName = "margins"; + } else if (viewTab.equals(tab)) { + tabName = "view"; + } else if (refTab.equals(tab)) { + tabName = "ref"; + } else if (browseTab.equals(tab)) { + tabName = "browse"; + } + return tabName; + } + + public Tab findTab(String tabName) { + switch (tabName) { + case "file": + return fileTab; + case "size": + return sizeTab; + case "crop": + return cropTab; + case "color": + return colorTab; + case "effects": + return effectsTab; + case "text": + return textTab; + case "cover": + return coverTab; + case "arc": + return arcTab; + case "shadow": + return shadowTab; + case "transform": + return transformTab; + case "margins": + return marginsTab; + case "view": + return viewTab; + case "ref": + return refTab; + case "browse": + return browseTab; + } + return null; + } + // Hotbar Methods @FXML - public void save() { + @Override + public void saveAction() { if (saveButton.isDisabled()) { return; } if (values.getSourceFile() == null) { - saveAs(); + saveAsAction(); return; } if (values.isIsConfirmBeforeSave()) { Alert alert = new Alert(Alert.AlertType.CONFIRMATION); alert.setTitle(getMyStage().getTitle()); alert.setContentText(AppVaribles.getMessage("SureOverrideFile")); + alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); ButtonType buttonSave = new ButtonType(AppVaribles.getMessage("Save")); ButtonType buttonSaveAs = new ButtonType(AppVaribles.getMessage("SaveAs")); ButtonType buttonCancel = new ButtonType(AppVaribles.getMessage("Cancel")); @@ -1385,7 +1446,7 @@ public void save() { if (result.get() == buttonCancel) { return; } else if (result.get() == buttonSaveAs) { - saveAs(); + saveAsAction(); return; } @@ -1394,8 +1455,11 @@ public void save() { task = new Task() { @Override protected Void call() throws Exception { - String format = values.getImageInfo().getImageFormat(); - final BufferedImage bufferedImage = FxmlImageTools.getBufferedImage(values.getCurrentImage()); + String format = "png"; + if (values.getImageInfo() != null) { + format = values.getImageInfo().getImageFormat(); + } + final BufferedImage bufferedImage = ImageTools.getBufferedImage(values.getCurrentImage()); if (task.isCancelled()) { return null; } @@ -1425,12 +1489,13 @@ public void run() { } @FXML - @Override - public void saveAs() { + public void saveAsAction() { try { final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(targetPathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(targetPathKey); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } fileChooser.getExtensionFilters().addAll(fileExtensionFilter); final File file = fileChooser.showSaveDialog(getMyStage()); if (file == null) { @@ -1442,7 +1507,7 @@ public void saveAs() { @Override protected Void call() throws Exception { String format = FileTools.getFileSuffix(file.getName()); - final BufferedImage bufferedImage = FxmlImageTools.getBufferedImage(values.getCurrentImage()); + final BufferedImage bufferedImage = ImageTools.getBufferedImage(values.getCurrentImage()); if (task.isCancelled()) { return null; } @@ -1549,7 +1614,7 @@ public void setBottomLabel() { str = AppVaribles.getMessage("CurrentPixels") + ":" + (int) values.getCurrentImage().getWidth() + "x" + (int) values.getCurrentImage().getHeight(); } else { str = AppVaribles.getMessage("Format") + ":" + values.getImageInfo().getImageFormat() + " " - + AppVaribles.getMessage("Pixels") + ":" + values.getImageInfo().getWidth() + "x" + values.getImageInfo().getHeight() + " " + + AppVaribles.getMessage("Pixels") + ":" + (int) values.getImage().getWidth() + "x" + (int) values.getImage().getHeight() + " " + AppVaribles.getMessage("Size") + ":" + FileTools.showFileSize(values.getSourceFile().length()) + " " + AppVaribles.getMessage("ModifyTime") + ":" + DateTools.datetimeToString(values.getSourceFile().lastModified()) + " " + AppVaribles.getMessage("CurrentPixels") + ":" + (int) values.getCurrentImage().getWidth() + "x" + (int) values.getCurrentImage().getHeight(); @@ -1573,17 +1638,17 @@ public void clickImage(MouseEvent event) { switch (scope.getScopeType()) { case All: - if (scope.getOperationType() == OperationType.ReplaceColor) { + if (isSettingColor) { colorPicker.setValue(color); } break; case Color: - if (scope.getOperationType() == OperationType.ReplaceColor + if (isSettingColor && event.getButton() == MouseButton.SECONDARY) { colorPicker.setValue(color); } else { - scope.addColor(color); + scope.addColor(ImageColor.converColor(color)); scopeColorsBox.getItems().add(color); scopeColorsBox.getSelectionModel().select(scopeColorsBox.getItems().size() - 1); scopeColorsBox.setVisibleRowCount(15); @@ -1592,7 +1657,7 @@ public void clickImage(MouseEvent event) { break; case Matting: - if (scope.getOperationType() == OperationType.ReplaceColor + if (isSettingColor && event.getButton() == MouseButton.SECONDARY) { colorPicker.setValue(color); } else { @@ -1605,7 +1670,7 @@ public void clickImage(MouseEvent event) { break; case Rectangle: - if (scope.getOperationType() == OperationType.ReplaceColor) { + if (isSettingColor) { colorPicker.setValue(color); } else { if (event.getButton() == MouseButton.PRIMARY) { @@ -1625,7 +1690,7 @@ public void clickImage(MouseEvent event) { break; case Circle: - if (scope.getOperationType() == OperationType.ReplaceColor) { + if (isSettingColor) { colorPicker.setValue(color); } else { if (event.getButton() == MouseButton.PRIMARY) { @@ -1648,11 +1713,11 @@ public void clickImage(MouseEvent event) { break; case RectangleColor: - if (scope.getOperationType() == OperationType.ReplaceColor + if (isSettingColor && event.getButton() == MouseButton.SECONDARY) { colorPicker.setValue(color); } else { - scope.addColor(color); + scope.addColor(ImageColor.converColor(color)); scopeColorsBox.getItems().add(color); scopeColorsBox.getSelectionModel().select(scopeColorsBox.getItems().size() - 1); scopeColorsBox.setVisibleRowCount(15); @@ -1662,11 +1727,11 @@ public void clickImage(MouseEvent event) { break; case CircleColor: - if (scope.getOperationType() == OperationType.ReplaceColor + if (isSettingColor && event.getButton() == MouseButton.SECONDARY) { colorPicker.setValue(color); } else { - scope.addColor(color); + scope.addColor(ImageColor.converColor(color)); scopeColorsBox.getItems().add(color); scopeColorsBox.getSelectionModel().select(scopeColorsBox.getItems().size() - 1); scopeColorsBox.setVisibleRowCount(15); @@ -1696,7 +1761,7 @@ public void scopeViewClicked(MouseEvent event) { switch (scope.getScopeType()) { case Color: - scope.addColor(color); + scope.addColor(ImageColor.converColor(color)); scopeColorsBox.getItems().add(color); scopeColorsBox.getSelectionModel().select(scopeColorsBox.getItems().size() - 1); scopeColorsBox.setVisibleRowCount(15); @@ -1795,7 +1860,7 @@ public void recovery() { setImageChanged(false); undoButton.setDisable(false); redoButton.setDisable(true); - + loadData(); } @FXML @@ -1824,6 +1889,24 @@ public void redoAction() { redoButton.setDisable(true); } + @FXML + public void refAction() { + values.setRefImage(imageView.getImage()); + values.setRefInfo(null); + if (!showRefCheck.isSelected()) { + showRefCheck.setSelected(true); + } else if (refView != null) { + refView.setImage(imageView.getImage()); + } + } + + @FXML + public void popAction() { + ImageViewerController controller + = (ImageViewerController) openStage(CommonValues.ImageViewerFxml, false); + controller.loadImage(sourceFile, imageView.getImage(), imageInformation, imageData); + } + @FXML public void clearScope() { scope.clearColors(); @@ -1859,18 +1942,12 @@ public void clearScope() { @Override protected void keyEventsHandler(KeyEvent event) { super.keyEventsHandler(event); - String key = event.getText(); - if (key == null || key.isEmpty()) { - return; - } if (event.isControlDown()) { + String key = event.getText(); + if (key == null || key.isEmpty()) { + return; + } switch (key) { - case "s": - case "S": - if (!saveButton.isDisabled()) { - save(); - } - break; case "r": case "R": if (!recoverButton.isDisabled()) { @@ -1895,29 +1972,19 @@ protected void keyEventsHandler(KeyEvent event) { hisBox.show(); } break; - case "1": - if (!wButton.isDisabled()) { - paneSize(); - } - break; - case "2": - if (!oButton.isDisabled()) { - imageSize(); + case "x": + if (!scopeClearButton.isDisabled()) { + clearScope(); } break; - case "3": - if (!inButton.isDisabled()) { - zoomIn(); + case "f": + if (!refButton.isDisabled()) { + refAction(); } break; - case "4": - if (!outButton.isDisabled()) { - zoomOut(); - } - break; - case "x": - if (!scopeClearButton.isDisabled()) { - clearScope(); + case "p": + if (!popButton.isDisabled()) { + popAction(); } break; default: @@ -2481,7 +2548,7 @@ public void handle(ActionEvent event) { protected void showLabels() { try { - if (values == null || scope == null || scope.getOperationType() == null) { + if (values == null || scope == null) { return; } @@ -2490,7 +2557,7 @@ protected void showLabels() { switch (scope.getScopeType()) { case All: - if (scope.getOperationType() == OperationType.ReplaceColor) { + if (isSettingColor) { imageLabel.setText(getMessage("ClickCurrentForNewColor")); } else { imageLabelBox.setAlignment(Pos.CENTER); @@ -2500,7 +2567,7 @@ protected void showLabels() { promptLabel.setText(""); break; case Matting: - if (scope.getOperationType() == OperationType.ReplaceColor) { + if (isSettingColor) { promptLabel.setText(getMessage("MattingComments2")); imageLabel.setText(getMessage("ClickCurrentForColors")); } else { @@ -2510,7 +2577,7 @@ protected void showLabels() { break; case Rectangle: - if (scope.getOperationType() == OperationType.ReplaceColor) { + if (isSettingColor) { promptLabel.setText(getMessage("RectangleLabel")); imageLabel.setText(getMessage("ClickCurrentForNewColor")); } else { @@ -2520,7 +2587,7 @@ protected void showLabels() { break; case Circle: - if (scope.getOperationType() == OperationType.ReplaceColor) { + if (isSettingColor) { promptLabel.setText(getMessage("CircleLabel")); imageLabel.setText(getMessage("ClickCurrentForNewColor")); } else { @@ -2530,7 +2597,7 @@ protected void showLabels() { break; case Color: - if (scope.getOperationType() == OperationType.ReplaceColor) { + if (isSettingColor) { promptLabel.setText(getMessage("ClickScopeForColorMatch")); imageLabel.setText(getMessage("ClickCurrentForColors")); } else { @@ -2540,7 +2607,7 @@ protected void showLabels() { break; case RectangleColor: - if (scope.getOperationType() == OperationType.ReplaceColor) { + if (isSettingColor) { promptLabel.setText(""); imageLabel.setText(getMessage("ClickScopeForRectangle")); scopePromptLabel.setText(getMessage("ClickCurrentForColors")); @@ -2552,7 +2619,7 @@ protected void showLabels() { break; case CircleColor: - if (scope.getOperationType() == OperationType.ReplaceColor) { + if (isSettingColor) { promptLabel.setText(""); imageLabel.setText(getMessage("ClickScopeForCircle")); scopePromptLabel.setText(getMessage("ClickCurrentForColors")); @@ -2588,25 +2655,6 @@ protected void hideScopePane() { } } - protected void adjustSplitPane() { - switch (splitPane.getItems().size()) { - case 3: - splitPane.getDividers().get(0).setPosition(0.33333); - splitPane.getDividers().get(1).setPosition(0.66666); -// splitPane.setDividerPositions(0.33, 0.33, 0.33); // This way not work! - break; - case 2: - splitPane.getDividers().get(0).setPosition(0.5); -// splitPane.setDividerPositions(0.5, 0.5); // This way not work! - break; - default: - splitPane.setDividerPositions(1); - break; - } - splitPane.layout(); - fitSize(); - } - @Override public boolean stageReloading() { if (isSwitchingTab) { @@ -2628,6 +2676,7 @@ public boolean checkSavingBeforeExit() { Alert alert = new Alert(Alert.AlertType.CONFIRMATION); alert.setTitle(getMyStage().getTitle()); alert.setContentText(AppVaribles.getMessage("ImageChanged")); + alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); ButtonType buttonSave = new ButtonType(AppVaribles.getMessage("Save")); ButtonType buttonSaveAs = new ButtonType(AppVaribles.getMessage("SaveAs")); ButtonType buttonNotSave = new ButtonType(AppVaribles.getMessage("NotSave")); @@ -2636,12 +2685,12 @@ public boolean checkSavingBeforeExit() { Optional result = alert.showAndWait(); if (result.get() == buttonSave) { - save(); + saveAction(); return true; } else if (result.get() == buttonNotSave) { return true; } else if (result.get() == buttonSaveAs) { - saveAs(); + saveAsAction(); return true; } else { return false; diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureConvolutionController.java b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureConvolutionController.java deleted file mode 100644 index 7c5c3bc60..000000000 --- a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureConvolutionController.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package mara.mybox.controller; - -import java.util.ArrayList; -import java.util.List; -import javafx.application.Platform; -import javafx.beans.value.ChangeListener; -import javafx.beans.value.ObservableValue; -import javafx.concurrent.Task; -import javafx.event.ActionEvent; -import javafx.fxml.FXML; -import javafx.scene.control.ComboBox; -import javafx.scene.control.Label; -import javafx.scene.control.Tooltip; -import javafx.scene.image.Image; -import javafx.scene.input.KeyEvent; -import javafx.scene.text.Font; -import javafx.stage.Modality; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.db.TableConvolutionKernel; -import mara.mybox.fxml.FxmlEffectTools; -import mara.mybox.fxml.FxmlTools; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.ConvolutionKernel; -import mara.mybox.objects.ImageScope; - -/** - * FXML Controller class - * - * @author mara - */ -public class ImageManufactureConvolutionController extends ImageManufactureController { - - private List kernels; - private ConvolutionKernel currentKernel; - - @FXML - private Label kernelLabel; - @FXML - private ComboBox kernelBox; - - @Override - protected void initializeNext2() { - try { - initCommon(); - initConvolutionTab(); - } catch (Exception e) { - logger.error(e.toString()); - } - } - - protected void initConvolutionTab() { - try { - - Tooltip tips = new Tooltip(getMessage("CTRL+k")); - tips.setFont(new Font(16)); - FxmlTools.quickTooltip(kernelBox, tips); - - kernelBox.setVisibleRowCount(15); - kernels = TableConvolutionKernel.read(); - loadList(kernels); - kernelBox.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue ov, Number oldValue, Number newValue) { - if (isSettingValues) { - return; - } - int index = newValue.intValue(); - if (index < 0 || index >= kernels.size()) { - return; - } - currentKernel = kernels.get(index); - applyKernel(); - } - }); - - } catch (Exception e) { - logger.error(e.toString()); - } - } - - @Override - protected void initInterface() { - try { - if (values == null || values.getImage() == null) { - return; - } - super.initInterface(); - values.getScope().setOperationType(ImageScope.OperationType.Convolution); - - isSettingValues = true; - - isSettingValues = false; - } catch (Exception e) { - logger.debug(e.toString()); - } - - } - - public void loadList(List records) { - isSettingValues = true; - kernels = records; - kernelBox.getItems().clear(); - if (records == null) { - return; - } - List names = new ArrayList<>(); - for (ConvolutionKernel k : kernels) { - names.add(k.getName()); - } - kernelBox.getItems().addAll(names); - isSettingValues = false; - } - - public void selectKernel(ConvolutionKernel kernel) { - if (kernelBox.getItems().contains(kernel.getName())) { - kernelBox.getSelectionModel().select(kernel.getName()); - } else { - applyKernel(kernel); - } - } - - @FXML - private void manageKernels(ActionEvent event) { - BaseController c = openStage(CommonValues.ConvolutionKernelManagerFxml, true); - c.setParentController(getMyController()); - c.setParentFxml(getMyFxml()); - } - - @Override - protected void keyEventsHandler(KeyEvent event) { - super.keyEventsHandler(event); - String key = event.getText(); - if (key == null || key.isEmpty()) { - return; - } - if (event.isControlDown()) { - switch (key) { - case "k": - case "K": - kernelBox.show(); - break; - } - } - } - - public void applyKernel(ConvolutionKernel inKernel) { - currentKernel = inKernel; - applyKernel(); - } - - private void applyKernel() { - if (isSettingValues || currentKernel == null) { - return; - } - task = new Task() { - @Override - protected Void call() throws Exception { - try { - final Image newImage; - if (scope == null || scope.getScopeType() == ImageScope.ScopeType.All) { - newImage = FxmlEffectTools.applyConvolution(values.getCurrentImage(), currentKernel); - } else if (scope.getScopeType() == ImageScope.ScopeType.Matting) { - newImage = FxmlEffectTools.applyConvolutionByMatting(values.getCurrentImage(), currentKernel, scope); - } else { - newImage = FxmlEffectTools.applyConvolutionByScope(values.getCurrentImage(), currentKernel, scope); - } - if (task.isCancelled()) { - return null; - } - - recordImageHistory(ImageOperationType.Convolution, newImage); - Platform.runLater(new Runnable() { - @Override - public void run() { - values.setUndoImage(values.getCurrentImage()); - values.setCurrentImage(newImage); - imageView.setImage(newImage); - setImageChanged(true); - } - }); - } catch (Exception e) { - logger.debug(e.toString()); - } - return null; - } - }; - openHandlingStage(task, Modality.WINDOW_MODAL); - Thread thread = new Thread(task); - thread.setDaemon(true); - thread.start(); - } - -} diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureCoverController.java b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureCoverController.java index db8e231fb..ab0e7087e 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureCoverController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureCoverController.java @@ -34,11 +34,10 @@ import javafx.stage.Modality; import javafx.util.Callback; import javax.imageio.ImageIO; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.fxml.FxmlCoverTools; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.CommonValues; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.fxml.image.FxmlCoverTools; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.getMessage; import static mara.mybox.fxml.FxmlTools.badStyle; /** @@ -394,7 +393,7 @@ private void checkShape() { } if (leftY >= rightY) { - leftYInput.setStyle(badStyle); + rightYInput.setStyle(badStyle); } } @@ -481,8 +480,10 @@ public void clickImage(MouseEvent event) { private void selectPicture(ActionEvent event) { try { final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(sourcePathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(sourcePathKey); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } fileChooser.getExtensionFilters().addAll(fileExtensionFilter); final File file = fileChooser.showOpenDialog(getMyStage()); if (file == null) { diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureCropController.java b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureCropController.java index a7c901354..975cec3d5 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureCropController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureCropController.java @@ -7,23 +7,19 @@ import javafx.concurrent.Task; import javafx.fxml.FXML; import javafx.scene.Cursor; -import javafx.scene.control.Button; import javafx.scene.control.TextField; import javafx.scene.control.ToolBar; -import javafx.scene.control.Tooltip; import javafx.scene.image.Image; import javafx.scene.input.MouseButton; import javafx.scene.input.MouseEvent; import javafx.scene.paint.Color; -import javafx.scene.text.Font; import javafx.stage.Modality; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.fxml.FxmlImageTools; -import mara.mybox.fxml.FxmlScopeTools; -import mara.mybox.fxml.FxmlTools; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.fxml.image.ImageTools; +import mara.mybox.fxml.image.FxmlScopeTools; import static mara.mybox.fxml.FxmlTools.badStyle; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.IntRectangle; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.data.IntRectangle; /** * @Author Mara @@ -35,8 +31,7 @@ public class ImageManufactureCropController extends ImageManufactureController { @FXML protected TextField cropLeftXInput, cropLeftYInput, cropRightXInput, cropRightYInput; - @FXML - protected Button cropOkButton; + @FXML protected ToolBar cropBar; @@ -62,10 +57,10 @@ protected void initInterface() { super.initInterface(); isSettingValues = true; - cropRightXInput.setText(values.getImageInfo().getWidth() * 3 / 4 + ""); - cropRightYInput.setText(values.getImageInfo().getHeight() * 3 / 4 + ""); - cropLeftXInput.setText(values.getImageInfo().getWidth() / 4 + ""); - cropLeftYInput.setText(values.getImageInfo().getHeight() / 4 + ""); + cropRightXInput.setText((int) values.getImage().getWidth() * 3 / 4 + ""); + cropRightYInput.setText((int) values.getImage().getHeight() * 3 / 4 + ""); + cropLeftXInput.setText((int) values.getImage().getWidth() / 4 + ""); + cropLeftYInput.setText((int) values.getImage().getHeight() / 4 + ""); isSettingValues = false; checkCropValues(); @@ -78,9 +73,6 @@ protected void initInterface() { protected void initCropTab() { try { - Tooltip tips = new Tooltip(getMessage("CropComments")); - tips.setFont(new Font(16)); - FxmlTools.setComments(cropBar, tips); cropLeftXInput.textProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue observable, @@ -110,7 +102,7 @@ public void changed(ObservableValue observable, } }); - cropOkButton.disableProperty().bind( + okButton.disableProperty().bind( cropLeftXInput.styleProperty().isEqualTo(badStyle) .or(cropLeftYInput.styleProperty().isEqualTo(badStyle)) .or(cropRightXInput.styleProperty().isEqualTo(badStyle)) @@ -133,7 +125,7 @@ protected void checkCropValues() { boolean areaValid = true; try { cropLeftX = Integer.valueOf(cropLeftXInput.getText()); - if (cropLeftX >= 0 && cropLeftX <= values.getCurrentImage().getWidth()) { + if (cropLeftX >= 0 && cropLeftX < values.getCurrentImage().getWidth()) { cropLeftXInput.setStyle(null); } else { cropLeftXInput.setStyle(badStyle); @@ -146,7 +138,7 @@ protected void checkCropValues() { try { cropLeftY = Integer.valueOf(cropLeftYInput.getText()); - if (cropLeftY >= 0 && cropLeftY <= values.getCurrentImage().getHeight()) { + if (cropLeftY >= 0 && cropLeftY < values.getCurrentImage().getHeight()) { cropLeftYInput.setStyle(null); } else { cropLeftYInput.setStyle(badStyle); @@ -159,7 +151,7 @@ protected void checkCropValues() { try { cropRightX = Integer.valueOf(cropRightXInput.getText()); - if (cropRightX >= 0 && cropRightX <= values.getCurrentImage().getWidth()) { + if (cropRightX >= 0 && cropRightX < values.getCurrentImage().getWidth()) { cropRightXInput.setStyle(null); } else { cropRightXInput.setStyle(badStyle); @@ -172,7 +164,7 @@ protected void checkCropValues() { try { cropRightY = Integer.valueOf(cropRightYInput.getText()); - if (cropRightY >= 0 && cropRightY <= values.getCurrentImage().getHeight()) { + if (cropRightY >= 0 && cropRightY < values.getCurrentImage().getHeight()) { cropRightYInput.setStyle(null); } else { cropRightYInput.setStyle(badStyle); @@ -220,7 +212,7 @@ protected Void call() throws Exception { @Override public void run() { imageView.setImage(newImage); -// popInformation(AppVaribles.getMessage("CropComments")); +// infoAction(AppVaribles.getMessage("CropComments")); } }); } catch (Exception e) { @@ -237,8 +229,20 @@ public void run() { @FXML @Override - public void copySelectionAction() { - copySelectionAction(values.getCurrentImage()); + public void selectAllAction() { + isSettingValues = true; + cropLeftXInput.setText("0"); + cropLeftYInput.setText("0"); + cropRightXInput.setText((int) (values.getCurrentImage().getWidth() - 1) + ""); + cropRightYInput.setText((int) (values.getCurrentImage().getHeight() - 1) + ""); + isSettingValues = false; + checkCropValues(); + } + + @FXML + @Override + public void copyAction() { + copyAction(values.getCurrentImage()); } @FXML @@ -274,13 +278,14 @@ public void clickImage(MouseEvent event) { } @FXML - public void cropAction() { + @Override + public void okAction() { imageView.setCursor(Cursor.OPEN_HAND); task = new Task() { @Override protected Void call() throws Exception { try { - final Image newImage = FxmlImageTools.cropImage(values.getCurrentImage(), + final Image newImage = ImageTools.cropImage(values.getCurrentImage(), cropLeftX, cropLeftY, cropRightX, cropRightY); if (task.isCancelled()) { return null; diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureEffectsController.java b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureEffectsController.java index ab88da4c9..e1d5412e9 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureEffectsController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureEffectsController.java @@ -1,10 +1,14 @@ package mara.mybox.controller; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import javafx.application.Platform; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.concurrent.Task; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.scene.control.Button; import javafx.scene.control.CheckBox; @@ -18,18 +22,24 @@ import javafx.scene.image.Image; import javafx.scene.input.KeyEvent; import javafx.scene.layout.HBox; -import javafx.scene.text.Font; import javafx.stage.Modality; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.fxml.FxmlEffectTools; -import mara.mybox.fxml.FxmlEffectTools.EffectsOperationType; -import mara.mybox.image.ImageConvertTools.Direction; -import static mara.mybox.objects.AppVaribles.getMessage; +import mara.mybox.db.TableConvolutionKernel; import mara.mybox.fxml.FxmlTools; import static mara.mybox.fxml.FxmlTools.badStyle; -import mara.mybox.image.ImageGrayTools; -import mara.mybox.objects.ConvolutionKernel; -import mara.mybox.objects.ImageScope; +import static mara.mybox.value.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.fxml.image.ImageConvolution; +import mara.mybox.fxml.image.PixelsOperation; +import mara.mybox.fxml.image.ImageBinary; +import mara.mybox.fxml.image.ImageContrast; +import mara.mybox.fxml.image.ImageGray; +import mara.mybox.fxml.image.ImageQuantization; +import mara.mybox.image.ImageContrast.ContrastAlgorithm; +import mara.mybox.image.ImageConvert.Direction; +import mara.mybox.image.ImageQuantization.QuantizationAlgorithm; +import mara.mybox.data.ConvolutionKernel; +import mara.mybox.image.PixelsOperation.OperationType; +import mara.mybox.value.CommonValues; /** * @Author Mara @@ -39,26 +49,27 @@ */ public class ImageManufactureEffectsController extends ImageManufactureController { - private EffectsOperationType effectType; - protected int intValue, direction; - protected int threadholding, threadholdingSmall, threadholdingBig; + private OperationType effectType; + protected int intPara1, intPara2, intPara3; + private List kernels; + private ConvolutionKernel kernel; + private ComboBox intBox, stringBox; + private Label intLabel, intLabel2, intLabel3, intLabel4, stringLabel; + private CheckBox valueCheck; + private TextField intInput, intInput2, intInput3, intInput4; + private RadioButton radio1, radio2, radio3, radio4; + private ToggleGroup radioGroup; + private Button setButton; + private QuantizationAlgorithm quantizationAlgorithm; + private ContrastAlgorithm contrastAlgorithm; @FXML protected ToggleGroup effectsGroup; @FXML - protected ComboBox intBox, stringBox; + protected HBox setBox; @FXML - protected TextField thresholdingInput, thresholdingMinInput, thresholdingMaxInput; - @FXML - protected RadioButton thresholdingRadio; - @FXML - protected Button okButton, calculateButton; - @FXML - protected HBox thresholdingBox1, thresholdingBox2; - @FXML - protected Label intLabel, stringLabel, smallLabel, bigLabel, thresholdLabel; - @FXML - protected CheckBox grayCheck; + protected RadioButton thresholdingRadio, posterizingRadio, bwRadio, + convolutionRadio, contrastRadio; public ImageManufactureEffectsController() { } @@ -84,45 +95,162 @@ public void changed(ObservableValue ov, }); checkEffetcsOperationType(); + FxmlTools.setComments(thresholdingRadio, new Tooltip(getMessage("ThresholdingComments"))); + FxmlTools.setComments(posterizingRadio, new Tooltip(getMessage("QuantizationComments"))); + FxmlTools.setComments(bwRadio, new Tooltip(getMessage("BWThresholdComments"))); + + } catch (Exception e) { + logger.error(e.toString()); + } + } + + @Override + protected void initInterface() { + try { + if (values == null || values.getImage() == null) { + return; + } + super.initInterface(); + + isSettingValues = true; + + isSettingValues = false; + } catch (Exception e) { + logger.debug(e.toString()); + } + + } + + private void removeTmpControls() { + intBox = null; + valueCheck = null; + intInput = intInput2 = intInput3 = intInput4 = null; + intLabel = intLabel2 = intLabel3 = intLabel4 = stringLabel = null; + radio1 = radio2 = radio3 = radio4 = null; + setButton = null; + scopeListBox.setDisable(false); + } + + private void checkEffetcsOperationType() { + try { + setBox.getChildren().clear(); + okButton.disableProperty().unbind(); + removeTmpControls(); + stringBox = null; + radioGroup = null; + + RadioButton selected = (RadioButton) effectsGroup.getSelectedToggle(); + String selectedString = selected.getText(); + if (getMessage("Blur").equals(selectedString)) { + effectType = OperationType.Blur; + makeBlurBox(); + + } else if (getMessage("Sharpen").equals(selectedString)) { + effectType = OperationType.Sharpen; + + } else if (getMessage("Clarity").equals(selectedString)) { + effectType = OperationType.Clarity; + + } else if (getMessage("EdgeDetection").equals(selectedString)) { + effectType = OperationType.EdgeDetect; + + } else if (getMessage("Emboss").equals(selectedString)) { + effectType = OperationType.Emboss; + makeEmbossBox(); + + } else if (getMessage("Posterizing").equals(selectedString)) { + effectType = OperationType.Quantization; + makePosterizingBox(); + + } else if (getMessage("Thresholding").equals(selectedString)) { + effectType = OperationType.Thresholding; + makeThresholdingBox(); + + } else if (getMessage("Gray").equals(selectedString)) { + effectType = OperationType.Gray; + + } else if (getMessage("BlackOrWhite").equals(selectedString)) { + effectType = OperationType.BlackOrWhite; + makeBlackWhiteBox(); + + } else if (getMessage("Sepia").equals(selectedString)) { + effectType = OperationType.Sepia; + makeSepiaBox(); + + } else if (getMessage("Contrast").equals(selectedString)) { + effectType = OperationType.Contrast; + makeContrastBox(); + + } else if (getMessage("Convolution").equals(selectedString)) { + effectType = OperationType.Convolution; + makeConvolutionBox(); + + } + + } catch (Exception e) { + logger.error(e.toString()); + } + } + + private void makeBlurBox() { + try { + intPara1 = 10; + intLabel = new Label(getMessage("Radius")); + intBox = new ComboBox(); + intBox.setEditable(true); + intBox.setPrefWidth(80); intBox.valueProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue ov, String oldValue, String newValue) { - int defaultValue = 0; - if (null != effectType) { - switch (effectType) { - case Blur: - defaultValue = 1; - break; - case Posterizing: - defaultValue = 32; - break; - case Emboss: - defaultValue = 3; - break; - default: - break; - } - } try { - String v = newValue; - int pos = v.indexOf(" "); - if (pos > 0) { - v = v.substring(0, pos); - } - intValue = Integer.valueOf(v); - if (intValue > 0) { + int v = Integer.valueOf(newValue); + if (v > 0) { + intPara1 = v; intBox.getEditor().setStyle(null); } else { - intValue = defaultValue; intBox.getEditor().setStyle(badStyle); } } catch (Exception e) { - intValue = defaultValue; intBox.getEditor().setStyle(badStyle); } } }); + intBox.getItems().addAll(Arrays.asList("10", "5", "3", "2", "1", "8", "15", "20", "30")); + intBox.getSelectionModel().select(0); + stringLabel = new Label(getMessage("Algorithm")); + stringBox = new ComboBox(); + stringBox.valueProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue ov, String oldValue, String newValue) { + try { + if (getMessage("AverageBlur").equals(newValue)) { + kernel = ConvolutionKernel.makeAverageBlur(intPara1); + } else { + kernel = ConvolutionKernel.makeGaussKernel(intPara1); + } + stringBox.getEditor().setStyle(null); + } catch (Exception e) { + stringBox.getEditor().setStyle(badStyle); + } + } + }); + stringBox.getItems().addAll(Arrays.asList(getMessage("AverageBlur"), getMessage("GaussianBlur"))); + stringBox.getSelectionModel().select(getMessage("AverageBlur")); + setBox.getChildren().addAll(stringLabel, stringBox, intLabel, intBox); + okButton.disableProperty().bind( + intBox.getEditor().styleProperty().isEqualTo(badStyle) + .or(stringBox.getEditor().styleProperty().isEqualTo(badStyle)) + ); + } catch (Exception e) { + logger.error(e.toString()); + } + } + private void makeEmbossBox() { + try { + intPara1 = Direction.Top; + stringLabel = new Label(getMessage("Direction")); + stringBox = new ComboBox(); stringBox.valueProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue ov, String oldValue, String newValue) { @@ -130,342 +258,655 @@ public void changed(ObservableValue ov, String oldValue, String newValue) { return; } if (getMessage("Top").equals(newValue)) { - direction = Direction.Top; + intPara1 = Direction.Top; } else if (getMessage("Bottom").equals(newValue)) { - direction = Direction.Bottom; + intPara1 = Direction.Bottom; } else if (getMessage("Left").equals(newValue)) { - direction = Direction.Top; + intPara1 = Direction.Top; } else if (getMessage("Right").equals(newValue)) { - direction = Direction.Right; + intPara1 = Direction.Right; } else if (getMessage("LeftTop").equals(newValue)) { - direction = Direction.LeftTop; + intPara1 = Direction.LeftTop; } else if (getMessage("RightBottom").equals(newValue)) { - direction = Direction.RightBottom; + intPara1 = Direction.RightBottom; } else if (getMessage("LeftBottom").equals(newValue)) { - direction = Direction.LeftBottom; + intPara1 = Direction.LeftBottom; } else if (getMessage("RightTop").equals(newValue)) { - direction = Direction.RightTop; + intPara1 = Direction.RightTop; } else { - direction = Direction.Top; + intPara1 = Direction.Top; } } }); + stringBox.getItems().addAll(Arrays.asList(getMessage("Top"), getMessage("Bottom"), + getMessage("Left"), getMessage("Right"), + getMessage("LeftTop"), getMessage("RightBottom"), + getMessage("LeftBottom"), getMessage("RightTop"))); + stringBox.getSelectionModel().select(getMessage("Top")); + intPara2 = 3; + intLabel = new Label(getMessage("Radius")); + intBox = new ComboBox(); + intBox.setEditable(false); + intBox.setPrefWidth(80); + intBox.valueProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue ov, String oldValue, String newValue) { + try { + int v = Integer.valueOf(newValue); + if (v > 0) { + intPara2 = v; + intBox.getEditor().setStyle(null); + } else { + intBox.getEditor().setStyle(badStyle); + } + } catch (Exception e) { + intBox.getEditor().setStyle(badStyle); + } + } + }); + intBox.getItems().addAll(Arrays.asList("3", "5")); + intBox.getSelectionModel().select(0); + valueCheck = new CheckBox(getMessage("Gray")); + valueCheck.setSelected(true); + setBox.getChildren().addAll(stringLabel, stringBox, intLabel, intBox, valueCheck); + okButton.disableProperty().bind( + intBox.getEditor().styleProperty().isEqualTo(badStyle) + .or(stringBox.getEditor().styleProperty().isEqualTo(badStyle)) + ); + } catch (Exception e) { + logger.error(e.toString()); + } + } - Tooltip tips = new Tooltip("0~255"); - tips.setFont(new Font(16)); - FxmlTools.quickTooltip(thresholdingMinInput, tips); - FxmlTools.quickTooltip(thresholdingMaxInput, tips); - - tips = new Tooltip(getMessage("CTRL+a")); - tips.setFont(new Font(16)); - FxmlTools.quickTooltip(okButton, tips); + private void makePosterizingBox() { + try { + quantizationAlgorithm = QuantizationAlgorithm.RGB_Uniform; + stringLabel = new Label(getMessage("Algorithm")); + stringBox = new ComboBox(); + stringBox.valueProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue ov, String oldValue, String newValue) { + if (getMessage("RGBUniformQuantization").equals(newValue)) { + quantizationAlgorithm = QuantizationAlgorithm.RGB_Uniform; + } else if (getMessage("HSBUniformQuantization").equals(newValue)) { + quantizationAlgorithm = QuantizationAlgorithm.HSB_Uniform; + } + } + }); + stringBox.getItems().addAll(Arrays.asList(getMessage("RGBUniformQuantization"), + getMessage("HSBUniformQuantization"))); + stringBox.getSelectionModel().select(getMessage("RGBUniformQuantization")); + intPara1 = 64; + intLabel = new Label(getMessage("ColorsNumber")); + intBox = new ComboBox(); + intBox.setEditable(false); + intBox.setPrefWidth(120); + intBox.valueProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue ov, String oldValue, String newValue) { + try { + int v = Integer.valueOf(newValue); + if (v > 0) { + intPara1 = v; + intBox.getEditor().setStyle(null); + } else { + intBox.getEditor().setStyle(badStyle); + } + } catch (Exception e) { + intBox.getEditor().setStyle(badStyle); + } + } + }); + intBox.getItems().addAll(Arrays.asList( + "64", "512", "8", "4096", "216", "343", "27", "125", "1000", "729", "1728", "8000")); + intBox.getSelectionModel().select(0); + valueCheck = new CheckBox(getMessage("Dithering")); + valueCheck.setSelected(true); + FxmlTools.setComments(valueCheck, new Tooltip(getMessage("DitherComments"))); + setBox.getChildren().addAll(stringLabel, stringBox, intLabel, intBox, valueCheck); + okButton.disableProperty().bind( + intBox.getEditor().styleProperty().isEqualTo(badStyle) + .or(stringBox.getEditor().styleProperty().isEqualTo(badStyle)) + ); + } catch (Exception e) { + logger.error(e.toString()); + } - tips = new Tooltip(getMessage("ThresholdingComments")); - tips.setFont(new Font(16)); - FxmlTools.setComments(thresholdingRadio, tips); + } - thresholdingInput.textProperty().addListener(new ChangeListener() { + private void makeThresholdingBox() { + try { + intPara1 = 128; + intLabel = new Label(getMessage("Threshold")); + intInput = new TextField(); + intInput.textProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue observable, String oldValue, String newValue) { - if (null != effectType) { - switch (effectType) { - case Thresholding: - checkThresholding(); - break; - case BlackOrWhite: - checkThresholdForBW(); - break; - case Sepia: - checkDensityForSepia(); - break; - default: - break; + try { + int v = Integer.valueOf(newValue); + if (v >= 0 && v <= 255) { + intPara1 = v; + intInput.setStyle(null); + } else { + popError("0~255"); + intInput.setStyle(badStyle); } + } catch (Exception e) { + popError("0~255"); + intInput.setStyle(badStyle); } } }); - thresholdingInput.setText("128"); + intInput.setPrefWidth(100); + intInput.setText("128"); + FxmlTools.quickTooltip(intInput, new Tooltip("0~255")); - thresholdingMinInput.textProperty().addListener(new ChangeListener() { + intPara2 = 0; + intLabel2 = new Label(getMessage("SmallValue")); + intInput2 = new TextField(); + intInput2.textProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue observable, String oldValue, String newValue) { - checkThresholding(); + try { + int v = Integer.valueOf(newValue); + if (v >= 0 && v <= 255) { + intPara2 = v; + intInput2.setStyle(null); + } else { + popError("0~255"); + intInput2.setStyle(badStyle); + } + } catch (Exception e) { + popError("0~255"); + intInput2.setStyle(badStyle); + } } }); - thresholdingMinInput.setText("0"); + intInput2.setPrefWidth(100); + intInput2.setText("0"); + FxmlTools.quickTooltip(intInput2, new Tooltip("0~255")); - thresholdingMaxInput.textProperty().addListener(new ChangeListener() { + intPara3 = 255; + intLabel3 = new Label(getMessage("BigValue")); + intInput3 = new TextField(); + intInput3.textProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue observable, String oldValue, String newValue) { - checkThresholding(); + try { + int v = Integer.valueOf(newValue); + if (v >= 0 && v <= 255) { + intPara3 = v; + intInput3.setStyle(null); + } else { + popError("0~255"); + intInput3.setStyle(badStyle); + } + } catch (Exception e) { + popError("0~255"); + intInput3.setStyle(badStyle); + } } }); - thresholdingMaxInput.setText("255"); + intInput3.setPrefWidth(100); + intInput3.setText("255"); + FxmlTools.quickTooltip(intInput3, new Tooltip("0~255")); + setBox.getChildren().addAll(intLabel, intInput, + intLabel2, intInput2, + intLabel3, intInput3); okButton.disableProperty().bind( - thresholdingInput.styleProperty().isEqualTo(badStyle) - .or(thresholdingMinInput.styleProperty().isEqualTo(badStyle)) - .or(thresholdingMaxInput.styleProperty().isEqualTo(badStyle)) + intInput.styleProperty().isEqualTo(badStyle) + .or(intInput3.styleProperty().isEqualTo(badStyle)) + .or(intInput2.styleProperty().isEqualTo(badStyle)) ); - } catch (Exception e) { logger.error(e.toString()); } + } - @Override - protected void initInterface() { + private void makeBlackWhiteBox() { try { - if (values == null || values.getImage() == null) { - return; - } - super.initInterface(); - values.getScope().setOperationType(ImageScope.OperationType.Effects); + intPara2 = 128; + intInput = new TextField(); + intInput.textProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue observable, + String oldValue, String newValue) { + try { + int v = Integer.valueOf(intInput.getText()); + if (v >= 0 && v <= 255) { + intPara2 = v; + intInput.setStyle(null); + } else { + intInput.setStyle(badStyle); + } + } catch (Exception e) { + intInput.setStyle(badStyle); + } + } + }); + intInput.setPrefWidth(100); + intInput.setText("128"); + FxmlTools.quickTooltip(intInput, new Tooltip("0~255")); - isSettingValues = true; + setButton = new Button(getMessage("Calculate")); + setButton.setOnAction(new EventHandler() { + @Override + public void handle(ActionEvent event) { + int scaleValue = ImageBinary.calculateThreshold(imageView.getImage()); + intInput.setText(scaleValue + ""); + } + }); - isSettingValues = false; - } catch (Exception e) { - logger.debug(e.toString()); - } + intPara1 = 1; + radioGroup = new ToggleGroup(); + radio1 = new RadioButton(getMessage("OTSU")); + radio1.setToggleGroup(radioGroup); + radio1.setUserData(1); + radio2 = new RadioButton(getMessage("Default")); + radio2.setToggleGroup(radioGroup); + radio2.setUserData(2); + radio3 = new RadioButton(getMessage("Threshold")); + radio3.setToggleGroup(radioGroup); + radio3.setUserData(3); + radioGroup.selectedToggleProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue ov, + Toggle old_toggle, Toggle new_toggle) { + if (radioGroup.getSelectedToggle() == null) { + return; + } + intPara1 = (int) ((RadioButton) new_toggle).getUserData(); + intInput.setDisable(intPara1 != 3); + setButton.setDisable(intPara1 != 3); + } + }); + radio1.setSelected(true); - } + valueCheck = new CheckBox(getMessage("Dithering")); + valueCheck.setSelected(true); + FxmlTools.setComments(valueCheck, new Tooltip(getMessage("DitherComments"))); - private void checkEffetcsOperationType() { - intLabel.setText(""); - stringLabel.setText(""); - smallLabel.setText(""); - bigLabel.setText(""); - thresholdLabel.setText(""); - intBox.setDisable(true); - stringBox.setDisable(true); - thresholdingBox1.setDisable(true); - thresholdingBox2.setDisable(true); - thresholdingInput.setStyle(null); - thresholdingMinInput.setStyle(null); - thresholdingMaxInput.setStyle(null); - grayCheck.setDisable(true); - calculateButton.setDisable(true); - RadioButton selected = (RadioButton) effectsGroup.getSelectedToggle(); - if (getMessage("Blur").equals(selected.getText())) { - effectType = EffectsOperationType.Blur; - intLabel.setText(getMessage("Radius")); - intBox.setDisable(false); - intBox.getItems().clear(); - intBox.getItems().addAll(Arrays.asList("10", "5", "3", "2", "1", "8", "15", "20", "30")); - intBox.setEditable(true); - intValue = 10; - intBox.getSelectionModel().select("10"); - } else if (getMessage("Sharpen").equals(selected.getText())) { - effectType = EffectsOperationType.Sharpen; - } else if (getMessage("Clarity").equals(selected.getText())) { - effectType = EffectsOperationType.Clarity; - } else if (getMessage("EdgeDetection").equals(selected.getText())) { - effectType = EffectsOperationType.EdgeDetect; - } else if (getMessage("Emboss").equals(selected.getText())) { - effectType = EffectsOperationType.Emboss; - intLabel.setText(getMessage("Radius")); - intBox.setDisable(false); - intBox.getItems().clear(); - intBox.getItems().addAll(Arrays.asList("3", "5")); - intBox.setEditable(false); - intValue = 3; - intBox.getSelectionModel().select("3"); - stringLabel.setText(getMessage("Direction")); - stringBox.setDisable(false); - stringBox.getItems().clear(); - stringBox.getItems().addAll(Arrays.asList(getMessage("Top"), getMessage("Bottom"), - getMessage("Left"), getMessage("Right"), - getMessage("LeftTop"), getMessage("RightBottom"), - getMessage("LeftBottom"), getMessage("RightTop"))); - direction = Direction.Top; - stringBox.getSelectionModel().select(getMessage("Top")); - grayCheck.setDisable(false); - } else if (getMessage("Posterizing").equals(selected.getText())) { - effectType = EffectsOperationType.Posterizing; - intLabel.setText(getMessage("Size")); - intBox.setDisable(false); - intBox.getItems().clear(); - intBox.getItems().addAll(Arrays.asList("64", "32", "128", "16")); - intBox.setEditable(false); - intBox.getSelectionModel().select("64"); - } else if (getMessage("Thresholding").equals(selected.getText())) { - effectType = EffectsOperationType.Thresholding; - thresholdLabel.setText(getMessage("Threshold")); - smallLabel.setText(getMessage("SmallValue")); - bigLabel.setText(getMessage("BigValue")); - thresholdingBox1.setDisable(false); - thresholdingBox2.setDisable(false); - checkThresholding(); - Tooltip tips = new Tooltip("0~255"); - tips.setFont(new Font(16)); - FxmlTools.quickTooltip(thresholdingInput, tips); - } else if (getMessage("Gray").equals(selected.getText())) { - effectType = EffectsOperationType.Gray; - - } else if (getMessage("BlackOrWhite").equals(selected.getText())) { - effectType = EffectsOperationType.BlackOrWhite; - thresholdingBox1.setDisable(false); - thresholdLabel.setText(getMessage("Threshold")); - thresholdingInput.setText("50"); - smallLabel.setText("%"); - calculateButton.setDisable(false); - checkThresholdForBW(); - Tooltip tips = new Tooltip("0~100"); - tips.setFont(new Font(16)); - FxmlTools.quickTooltip(thresholdingInput, tips); - - } else if (getMessage("Sepia").equals(selected.getText())) { - effectType = EffectsOperationType.Sepia; - thresholdingBox1.setDisable(false); - thresholdLabel.setText(getMessage("Intensity")); - thresholdingInput.setText("80"); - checkDensityForSepia(); - Tooltip tips = new Tooltip("0~255"); - tips.setFont(new Font(16)); - FxmlTools.quickTooltip(thresholdingInput, tips); + setBox.getChildren().addAll(radio1, radio2, radio3, + intInput, setButton, valueCheck); + okButton.disableProperty().bind( + intInput.styleProperty().isEqualTo(badStyle) + ); + } catch (Exception e) { + logger.error(e.toString()); } + } - private void checkThresholding() { - try { - threadholding = Integer.valueOf(thresholdingInput.getText()); - if (threadholding >= 0 && threadholding <= 255) { - thresholdingInput.setStyle(null); - } else { - popError("0~100"); - thresholdingInput.setStyle(badStyle); - } - } catch (Exception e) { - popError("0~100"); - thresholdingInput.setStyle(badStyle); - } + private void makeSepiaBox() { try { - threadholdingSmall = Integer.valueOf(thresholdingMinInput.getText()); - if (threadholdingSmall >= 0 && threadholdingSmall <= 255) { - thresholdingMinInput.setStyle(null); - } else { - thresholdingMinInput.setStyle(badStyle); - } - } catch (Exception e) { - thresholdingMinInput.setStyle(badStyle); - } - try { - threadholdingBig = Integer.valueOf(thresholdingMaxInput.getText()); - if (threadholdingBig >= 0 && threadholdingBig <= 255) { - thresholdingMaxInput.setStyle(null); - } else { - thresholdingMaxInput.setStyle(badStyle); - } + intPara1 = 80; + intLabel = new Label(getMessage("Intensity")); + intInput = new TextField(); + intInput.textProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue observable, + String oldValue, String newValue) { + try { + int v = Integer.valueOf(intInput.getText()); + if (v >= 0 && v <= 255) { + intPara1 = v; + intInput.setStyle(null); + } else { + intInput.setStyle(badStyle); + popError("0~255"); + } + } catch (Exception e) { + popError("0~255"); + intInput.setStyle(badStyle); + } + } + }); + intInput.setPrefWidth(100); + intInput.setText("80"); + FxmlTools.quickTooltip(intInput, new Tooltip("0~255")); + + setBox.getChildren().addAll(intLabel, intInput); + okButton.disableProperty().bind( + intInput.styleProperty().isEqualTo(badStyle) + ); } catch (Exception e) { - thresholdingMaxInput.setStyle(badStyle); + logger.error(e.toString()); } + } - private void checkThresholdForBW() { + private void makeConvolutionBox() { try { - threadholding = Integer.valueOf(thresholdingInput.getText()); - if (threadholding >= 0 && threadholding <= 100) { - thresholdingInput.setStyle(null); - } else { - thresholdingInput.setStyle(badStyle); - popError("0~100"); + stringLabel = new Label(getMessage("ConvolutionKernel")); + stringBox = new ComboBox(); + kernel = null; + if (kernels == null) { + kernels = TableConvolutionKernel.read(); } + loadKernelsList(kernels); + stringBox.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue ov, Number oldValue, Number newValue) { + int index = newValue.intValue(); + if (index < 0 || index >= kernels.size()) { + kernel = null; + stringBox.getEditor().setStyle(badStyle); + return; + } + kernel = kernels.get(index); + stringBox.getEditor().setStyle(null); + } + }); + FxmlTools.quickTooltip(stringBox, new Tooltip(getMessage("CTRL+k"))); + setButton = new Button(getMessage("ManageDot")); + setButton.setOnAction(new EventHandler() { + @Override + public void handle(ActionEvent event) { + BaseController c = openStage(CommonValues.ConvolutionKernelManagerFxml, false); + c.setParentController(getMyController()); + c.setParentFxml(getMyFxml()); + } + }); + setBox.getChildren().addAll(stringLabel, stringBox, setButton); + okButton.disableProperty().bind( + stringBox.getEditor().styleProperty().isEqualTo(badStyle) + ); } catch (Exception e) { - popError("0~100"); - thresholdingInput.setStyle(badStyle); + logger.error(e.toString()); } + } - private void checkDensityForSepia() { + private void makeContrastBox() { try { - threadholding = Integer.valueOf(thresholdingInput.getText()); - if (threadholding >= 0 && threadholding <= 255) { - thresholdingInput.setStyle(null); - } else { - popError("0~255"); - thresholdingInput.setStyle(badStyle); - } + contrastAlgorithm = ContrastAlgorithm.Gray_Histogram_Equalization; + stringLabel = new Label(getMessage("Algorithm")); + stringBox = new ComboBox(); + stringBox.getItems().addAll(Arrays.asList( + getMessage("HSBHistogramEqualization"), + getMessage("GrayHistogramEqualization"), + getMessage("GrayHistogramStretching"), + getMessage("GrayHistogramShifting") + // getMessage("LumaHistogramEqualization"), + // getMessage("AdaptiveHistogramEqualization") + )); + stringBox.getSelectionModel().select(0); + stringBox.valueProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue ov, String oldValue, String newValue) { + if (setBox.getChildren() != null) { + if (setBox.getChildren().contains(intInput)) { + setBox.getChildren().removeAll(intLabel, intInput); + } + if (setBox.getChildren().contains(intInput2)) { + setBox.getChildren().removeAll(intLabel2, intInput2); + } + } + okButton.disableProperty().unbind(); + if (getMessage("GrayHistogramEqualization").equals(newValue)) { + contrastAlgorithm = ContrastAlgorithm.Gray_Histogram_Equalization; + } else if (getMessage("GrayHistogramStretching").equals(newValue)) { + contrastAlgorithm = ContrastAlgorithm.Gray_Histogram_Stretching; + intPara1 = 100; + intLabel = new Label(getMessage("LeftThreshold")); + intInput = new TextField(); + intInput.textProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue observable, + String oldValue, String newValue) { + try { + int v = Integer.valueOf(intInput.getText()); + if (v >= 0) { + intPara1 = v; + intInput.setStyle(null); + } else { + intInput.setStyle(badStyle); + } + } catch (Exception e) { + intInput.setStyle(badStyle); + } + } + }); + intInput.setPrefWidth(100); + intInput.setText("100"); + + intPara2 = 100; + intLabel2 = new Label(getMessage("RightThreshold")); + intInput2 = new TextField(); + intInput2.textProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue observable, + String oldValue, String newValue) { + try { + int v = Integer.valueOf(intInput2.getText()); + if (v >= 0) { + intPara2 = v; + intInput2.setStyle(null); + } else { + intInput2.setStyle(badStyle); + } + } catch (Exception e) { + intInput2.setStyle(badStyle); + } + } + }); + intInput2.setPrefWidth(100); + intInput2.setText("100"); + + setBox.getChildren().addAll(intLabel, intInput, intLabel2, intInput2); + okButton.disableProperty().bind( + intInput.styleProperty().isEqualTo(badStyle) + .or(intInput2.styleProperty().isEqualTo(badStyle)) + .or(stringBox.getEditor().styleProperty().isEqualTo(badStyle)) + ); + } else if (getMessage("GrayHistogramShifting").equals(newValue)) { + contrastAlgorithm = ContrastAlgorithm.Gray_Histogram_Shifting; + intPara1 = 80; + intLabel = new Label(getMessage("Offset")); + intInput = new TextField(); + intInput.textProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue observable, + String oldValue, String newValue) { + try { + int v = Integer.valueOf(intInput.getText()); + if (v >= -255 && v <= 255) { + intPara1 = v; + intInput.setStyle(null); + } else { + intInput.setStyle(badStyle); + popError("-255 ~ 255"); + } + } catch (Exception e) { + popError("-255 ~ 255"); + } + } + }); + intInput.setPrefWidth(100); + intInput.setText("10"); + FxmlTools.quickTooltip(intInput, new Tooltip("-255 ~ 255")); + setBox.getChildren().addAll(intLabel, intInput); + okButton.disableProperty().bind( + intInput.styleProperty().isEqualTo(badStyle) + .or(stringBox.getEditor().styleProperty().isEqualTo(badStyle)) + ); + } else if (getMessage("LumaHistogramEqualization").equals(newValue)) { + contrastAlgorithm = ContrastAlgorithm.Luma_Histogram_Equalization; + } else if (getMessage("HSBHistogramEqualization").equals(newValue)) { + contrastAlgorithm = ContrastAlgorithm.HSB_Histogram_Equalization; + } else if (getMessage("AdaptiveHistogramEqualization").equals(newValue)) { + contrastAlgorithm = ContrastAlgorithm.Adaptive_Histogram_Equalization; + } + } + }); + + setBox.getChildren().addAll(stringLabel, stringBox); } catch (Exception e) { - popError("0~255"); - thresholdingInput.setStyle(badStyle); + logger.error(e.toString()); } } - @FXML - private void calculateAction() { - int scaleValue = ImageGrayTools.calculateThreshold(values.getSourceFile()); - scaleValue = scaleValue * 100 / 256; - thresholdingInput.setText(scaleValue + ""); - } - @Override protected void keyEventsHandler(KeyEvent event) { super.keyEventsHandler(event); - String key = event.getText(); - if (key == null || key.isEmpty()) { - return; - } if (event.isControlDown()) { + String key = event.getText(); + if (key == null || key.isEmpty()) { + return; + } switch (key) { - case "a": - case "A": - effectsAction(); + case "k": + case "K": + if (stringBox != null) { + stringBox.show(); + } break; } } } + public void applyKernel(ConvolutionKernel kernel) { + if (effectType != OperationType.Convolution || stringBox == null) { + return; + } + convolutionRadio.fire(); + if (stringBox.getItems().contains(kernel.getName())) { + stringBox.getSelectionModel().select(kernel.getName()); + } else { + stringBox.getSelectionModel().select(-1); + } + this.kernel = kernel; + okAction(); + } + + public void loadKernelsList(List records) { + if (effectType != OperationType.Convolution || stringBox == null) { + return; + } + kernels = records; + stringBox.getItems().clear(); + if (kernels != null && !kernels.isEmpty()) { + List names = new ArrayList<>(); + for (ConvolutionKernel k : kernels) { + names.add(k.getName()); + } + stringBox.getItems().addAll(names); + stringBox.getSelectionModel().select(0); + stringBox.getEditor().setStyle(null); + } else { + stringBox.getEditor().setStyle(badStyle); + } + } + @FXML - public void effectsAction() { + @Override + public void okAction() { if (null == effectType) { return; } task = new Task() { + private Image newImage; + @Override protected Void call() throws Exception { - final Image newImage; - ConvolutionKernel convolutionKernel; + PixelsOperation pixelsOperation; + ImageConvolution imageConvolution; switch (effectType) { + case Contrast: + ImageContrast imageContrast = new ImageContrast(values.getCurrentImage(), contrastAlgorithm); + imageContrast.setIntPara1(intPara1); + imageContrast.setIntPara2(intPara2); + newImage = imageContrast.operateFxImage(); + break; + case Convolution: + if (kernel == null) { + int index = stringBox.getSelectionModel().getSelectedIndex(); + if (kernels == null || kernels.isEmpty() || index < 0) { + return null; + } + kernel = kernels.get(index); + } + imageConvolution = new ImageConvolution(values.getCurrentImage(), scope, kernel); + newImage = imageConvolution.operateFxImage(); + break; case Blur: - convolutionKernel = ConvolutionKernel.makeAverageBlur(intValue); - newImage = FxmlEffectTools.applyConvolution(values.getCurrentImage(), convolutionKernel, scope); + if (kernel == null) { + return null; + } + imageConvolution = new ImageConvolution(values.getCurrentImage(), scope, kernel); + newImage = imageConvolution.operateFxImage(); break; case Sharpen: - convolutionKernel = ConvolutionKernel.makeSharpen3b(); - newImage = FxmlEffectTools.applyConvolution(values.getCurrentImage(), convolutionKernel, scope); + kernel = ConvolutionKernel.makeSharpen3b(); + imageConvolution = new ImageConvolution(values.getCurrentImage(), scope, kernel); + newImage = imageConvolution.operateFxImage(); break; case Clarity: - convolutionKernel = ConvolutionKernel.makeUnsharpMasking5(); - newImage = FxmlEffectTools.applyConvolution(values.getCurrentImage(), convolutionKernel, scope); + kernel = ConvolutionKernel.makeUnsharpMasking5(); + imageConvolution = new ImageConvolution(values.getCurrentImage(), scope, kernel); + newImage = imageConvolution.operateFxImage(); break; case EdgeDetect: - convolutionKernel = ConvolutionKernel.makeEdgeDetection3b(); - newImage = FxmlEffectTools.applyConvolution(values.getCurrentImage(), convolutionKernel, scope); + kernel = ConvolutionKernel.makeEdgeDetection3b(); + imageConvolution = new ImageConvolution(values.getCurrentImage(), scope, kernel); + newImage = imageConvolution.operateFxImage(); break; case Emboss: - convolutionKernel = ConvolutionKernel.makeEmbossKernel(direction, intValue, grayCheck.isSelected()); - newImage = FxmlEffectTools.applyConvolution(values.getCurrentImage(), convolutionKernel, scope); + kernel = ConvolutionKernel.makeEmbossKernel(intPara1, intPara2, valueCheck.isSelected()); + imageConvolution = new ImageConvolution(values.getCurrentImage(), scope, kernel); + newImage = imageConvolution.operateFxImage(); + break; + case Quantization: + int channelSize = (int) Math.round(Math.pow(intPara1, 1.0 / 3.0)); + ImageQuantization quantization = new ImageQuantization(values.getCurrentImage()); + quantization.setScope(scope); + quantization.set(quantizationAlgorithm, channelSize); + quantization.setIsDithering(valueCheck.isSelected()); + newImage = quantization.operateFxImage(); break; case Thresholding: - newImage = FxmlEffectTools.thresholdingImage(values.getCurrentImage(), - threadholding, threadholdingSmall, threadholdingBig, scope); + pixelsOperation = new PixelsOperation(values.getCurrentImage(), scope, effectType); + pixelsOperation.setIntPara1(intPara1); + pixelsOperation.setIntPara2(intPara2); + pixelsOperation.setIntPara3(intPara3); + pixelsOperation.setIsDithering(false); + newImage = pixelsOperation.operateFxImage(); break; - case Posterizing: - newImage = FxmlEffectTools.posterizingImage(values.getCurrentImage(), intValue, scope); + case BlackOrWhite: + ImageBinary imageBinary; + switch (intPara1) { + case 2: + imageBinary = new ImageBinary(values.getCurrentImage(), scope, -1); + break; + case 3: + imageBinary = new ImageBinary(values.getCurrentImage(), scope, intPara2); + break; + default: + int t = ImageBinary.calculateThreshold(values.getCurrentImage()); + imageBinary = new ImageBinary(values.getCurrentImage(), scope, t); + break; + } + imageBinary.setIsDithering(valueCheck.isSelected()); + newImage = imageBinary.operateFxImage(); break; case Gray: - case BlackOrWhite: + ImageGray imageGray = new ImageGray(values.getCurrentImage(), scope); + newImage = imageGray.operateFxImage(); + break; case Sepia: - newImage = FxmlEffectTools.makeColor(values.getCurrentImage(), effectType, threadholding, scope); + pixelsOperation = new PixelsOperation(values.getCurrentImage(), scope, effectType); + pixelsOperation.setIntPara1(intPara1); + newImage = pixelsOperation.operateFxImage(); break; default: return null; } - if (task.isCancelled()) { + if (task.isCancelled() || newImage == null) { return null; } recordImageHistory(ImageOperationType.Effects, newImage); diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureFileController.java b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureFileController.java index 297677848..989fd2db2 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureFileController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureFileController.java @@ -2,15 +2,14 @@ import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; -import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.control.RadioButton; import javafx.scene.control.Toggle; import javafx.scene.control.ToggleGroup; import javafx.scene.control.ToolBar; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.ImageScope; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.AppVaribles; +import mara.mybox.image.ImageScope; /** * @Author Mara @@ -94,75 +93,6 @@ public void changed(ObservableValue ov, Boolean old_val, Bool } } - @Override - protected void afterInfoLoaded() { - super.afterInfoLoaded(); - fileBar.setDisable(false); - saveCheck.setDisable(true); - } - - @Override - public void afterImageLoaded() { - try { - super.afterImageLoaded(); - - if (imageInformation.isIsSampled()) { - hotBar.setDisable(false); - showRefCheck.setDisable(true); - hisBox.setDisable(true); - undoButton.setDisable(true); - redoButton.setDisable(true); - recoverButton.setDisable(true); - saveButton.setDisable(true); - - browseTab.setDisable(true); - viewTab.setDisable(true); - colorTab.setDisable(true); - effectsTab.setDisable(true); - convolutionTab.setDisable(true); - sizeTab.setDisable(true); - refTab.setDisable(true); - transformTab.setDisable(true); - textTab.setDisable(true); - coverTab.setDisable(true); - arcTab.setDisable(true); - shadowTab.setDisable(true); - marginsTab.setDisable(true); - cropTab.setDisable(true); - - } - isSettingValues = true; - values.setSourceFile(sourceFile); - values.setImage(image); - values.setImageInfo(imageInformation); - values.setCurrentImage(image); - isSettingValues = false; - - if (image == null || imageInformation.isIsSampled()) { - return; - } - - isSettingValues = true; - values.setRefImage(image); - values.setRefInfo(imageInformation); - setImageChanged(false); - values.setScope(new ImageScope(image)); - scope = values.getScope(); - - recordImageHistory(ImageOperationType.Load, image); - saveCheck.setDisable(false); - if (initTab != null) { - switchTab(initTab); - } else { - initInterface(); - } - isSettingValues = false; - - } catch (Exception e) { - logger.debug(e.toString()); - } - } - private void checkSaveAsType() { try { RadioButton selected = (RadioButton) saveAsGroup.getSelectedToggle(); @@ -183,17 +113,6 @@ private void checkSaveAsType() { } } - @FXML - @Override - protected void selectSourceFile(ActionEvent event) { - if (values == null || values.getCurrentImage() != null && values.isImageChanged()) { - if (!checkSavingBeforeExit()) { - return; - } - } - super.selectSourceFile(event); - } - @Override protected void initInterface() { try { @@ -205,6 +124,8 @@ protected void initInterface() { isSettingValues = true; fileBar.setDisable(false); saveAsBar.setDisable(false); + infoButton.setDisable(imageInformation == null); + metaButton.setDisable(imageInformation == null); isSettingValues = false; } catch (Exception e) { logger.debug(e.toString()); @@ -212,4 +133,22 @@ protected void initInterface() { } + @Override + protected void afterInfoLoaded() { + super.afterInfoLoaded(); + fileBar.setDisable(false); + saveCheck.setDisable(true); + } + + @Override + public void afterImageLoaded() { + try { + super.afterImageLoaded(); + saveCheck.setDisable(false); + + } catch (Exception e) { + logger.debug(e.toString()); + } + } + } diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureMarginsController.java b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureMarginsController.java index d687aca8b..592d92e2c 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureMarginsController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureMarginsController.java @@ -11,7 +11,6 @@ import javafx.scene.control.CheckBox; import javafx.scene.control.ColorPicker; import javafx.scene.control.ComboBox; -import javafx.scene.control.Label; import javafx.scene.control.RadioButton; import javafx.scene.control.TextField; import javafx.scene.control.Toggle; @@ -22,11 +21,11 @@ import javafx.scene.layout.HBox; import javafx.scene.paint.Color; import javafx.stage.Modality; -import static mara.mybox.objects.AppVaribles.logger; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.CommonValues; -import mara.mybox.fxml.FxmlMarginsTools; -import mara.mybox.objects.AppVaribles; +import static mara.mybox.value.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.value.CommonValues; +import mara.mybox.fxml.image.FxmlMarginsTools; +import mara.mybox.value.AppVaribles; import static mara.mybox.fxml.FxmlTools.badStyle; /** @@ -47,14 +46,12 @@ public class ImageManufactureMarginsController extends ImageManufactureControlle @FXML protected ColorPicker marginsColorPicker; @FXML - protected Button marginsWhiteButton, marginsBlackButton, marginsOkButton, marginsTrButton; + protected Button marginsWhiteButton, marginsBlackButton, marginsTrButton; @FXML protected CheckBox marginsTopCheck, marginsBottomCheck, marginsLeftCheck, marginsRightCheck; @FXML private HBox colorBox, distanceBox, widthBox; @FXML - private Label promptLabel; - @FXML private TextField distanceInput; public ImageManufactureMarginsController() { @@ -85,7 +82,8 @@ protected void initInterface() { super.initInterface(); isSettingValues = true; - if (CommonValues.NoAlphaImages.contains(values.getImageInfo().getImageFormat())) { + if (values.getImageInfo() != null + && CommonValues.NoAlphaImages.contains(values.getImageInfo().getImageFormat())) { marginsTrButton.setDisable(true); } else { marginsTrButton.setDisable(false); @@ -127,7 +125,7 @@ public void changed(ObservableValue ov, String oldValue, String newValue) { }); marginWidthBox.getSelectionModel().select(0); - marginsOkButton.disableProperty().bind( + okButton.disableProperty().bind( marginWidthBox.getEditor().styleProperty().isEqualTo(badStyle) .or(distanceInput.styleProperty().isEqualTo(badStyle)) ); @@ -234,7 +232,8 @@ public void clickImage(MouseEvent event) { } @FXML - public void marginsAction() { + @Override + public void okAction() { if (!marginsTopCheck.isSelected() && !marginsBottomCheck.isSelected() && !marginsLeftCheck.isSelected() diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureRefController.java b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureRefController.java index 28142484a..c5ecb5036 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureRefController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureRefController.java @@ -7,9 +7,9 @@ import javafx.scene.control.CheckBox; import javafx.scene.control.ToolBar; import javafx.stage.FileChooser; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.CommonValues; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.AppVaribles; +import mara.mybox.value.CommonValues; /** * @Author Mara @@ -85,8 +85,8 @@ protected void checkReferenceImage() { public void selectReference() { try { final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(sourcePathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(sourcePathKey); + if ( path.exists() ) fileChooser.setInitialDirectory(path); fileChooser.getExtensionFilters().addAll(fileExtensionFilter); File file = fileChooser.showOpenDialog(getMyStage()); if (file == null) { diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureShadowController.java b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureShadowController.java index df57ffa85..029846978 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureShadowController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureShadowController.java @@ -12,10 +12,10 @@ import javafx.scene.image.Image; import javafx.scene.paint.Color; import javafx.stage.Modality; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.CommonValues; -import mara.mybox.fxml.FxmlImageTools; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.AppVaribles; +import mara.mybox.value.CommonValues; +import mara.mybox.fxml.image.ImageTools; import static mara.mybox.fxml.FxmlTools.badStyle; /** @@ -60,17 +60,18 @@ protected void initInterface() { isSettingValues = true; - if (CommonValues.NoAlphaImages.contains(values.getImageInfo().getImageFormat())) { + if (values.getImageInfo() != null + && CommonValues.NoAlphaImages.contains(values.getImageInfo().getImageFormat())) { transShadowButton.setDisable(true); } else { transShadowButton.setDisable(false); } shadowBox.getItems().clear(); - shadowBox.getItems().addAll(Arrays.asList(values.getImageInfo().getWidth() / 100 + "", - values.getImageInfo().getWidth() / 50 + "", - values.getImageInfo().getWidth() / 200 + "", - values.getImageInfo().getWidth() / 30 + "", + shadowBox.getItems().addAll(Arrays.asList((int) values.getImage().getWidth() / 100 + "", + (int) values.getImage().getWidth() / 50 + "", + (int) values.getImage().getWidth() / 200 + "", + (int) values.getImage().getWidth() / 30 + "", "0", "4", "5", "3", "2", "1", "6")); shadowBox.getSelectionModel().select(0); @@ -131,7 +132,7 @@ public void shadowAction() { return; } try { - Image newImage = FxmlImageTools.addShadowFx(values.getCurrentImage(), shadow, shadowColorPicker.getValue()); + Image newImage = ImageTools.addShadowFx(values.getCurrentImage(), shadow, shadowColorPicker.getValue()); if (newImage != null) { recordImageHistory(ImageOperationType.Shadow, newImage); values.setUndoImage(values.getCurrentImage()); @@ -145,7 +146,7 @@ public void shadowAction() { } - Image newImage = FxmlImageTools.addShadowBigFx(values.getCurrentImage(), shadow, shadowColorPicker.getValue()); + Image newImage = ImageTools.addShadowBigFx(values.getCurrentImage(), shadow, shadowColorPicker.getValue()); if (newImage != null) { recordImageHistory(ImageOperationType.Shadow, newImage); values.setUndoImage(values.getCurrentImage()); @@ -159,7 +160,7 @@ public void shadowAction() { task = new Task() { @Override protected Void call() throws Exception { - final Image newImage = FxmlImageTools.addShadow(values.getCurrentImage(), shadow, shadowColorPicker.getValue()); + final Image newImage = ImageTools.addShadow(values.getCurrentImage(), shadow, shadowColorPicker.getValue()); if (task.isCancelled()) { return null; } diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureSizeController.java b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureSizeController.java index 816e3016e..1f7970d67 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureSizeController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureSizeController.java @@ -9,7 +9,6 @@ import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.scene.Scene; -import javafx.scene.control.Button; import javafx.scene.control.CheckBox; import javafx.scene.control.ChoiceBox; import javafx.scene.control.ComboBox; @@ -23,14 +22,14 @@ import javafx.stage.Modality; import javafx.stage.Stage; import javafx.stage.WindowEvent; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.image.ImageConvertTools; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.ImageAttributes; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.image.ImageConvert; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.value.CommonValues; +import mara.mybox.data.ImageAttributes; import static mara.mybox.fxml.FxmlTools.badStyle; -import mara.mybox.fxml.FxmlImageTools; +import mara.mybox.fxml.image.ImageTools; /** * @Author Mara @@ -49,8 +48,6 @@ public class ImageManufactureSizeController extends ImageManufactureController { @FXML protected ToggleGroup pixelsGroup; @FXML - protected Button pixelsOkButton; - @FXML protected CheckBox keepRatioCheck; @FXML protected TextField widthInput, heightInput; @@ -79,14 +76,11 @@ protected void initInterface() { return; } super.initInterface(); - isSettingValues = true; - - widthInput.setText(values.getImageInfo().getWidth() + ""); - heightInput.setText(values.getImageInfo().getHeight() + ""); - attributes.setSourceWidth(values.getImageInfo().getWidth()); - attributes.setSourceHeight(values.getImageInfo().getHeight()); - + widthInput.setText((int) values.getImage().getWidth() + ""); + heightInput.setText((int) values.getImage().getHeight() + ""); + attributes.setSourceWidth((int) values.getImage().getWidth()); + attributes.setSourceHeight((int) values.getImage().getHeight()); isSettingValues = false; } catch (Exception e) { logger.debug(e.toString()); @@ -124,7 +118,7 @@ public void changed(ObservableValue ov, Boolean oldValue, Boo }); checkRatio(); - pixelsOkButton.disableProperty().bind( + okButton.disableProperty().bind( widthInput.styleProperty().isEqualTo(badStyle) .or(heightInput.styleProperty().isEqualTo(badStyle)) .or(scaleBox.getEditor().styleProperty().isEqualTo(badStyle)) @@ -236,15 +230,15 @@ private void checkPixelsHeight() { protected void checkRatioAdjustion(String s) { try { if (getMessage("BaseOnWidth").equals(s)) { - attributes.setRatioAdjustion(ImageConvertTools.KeepRatioType.BaseOnWidth); + attributes.setRatioAdjustion(ImageConvert.KeepRatioType.BaseOnWidth); } else if (getMessage("BaseOnHeight").equals(s)) { - attributes.setRatioAdjustion(ImageConvertTools.KeepRatioType.BaseOnHeight); + attributes.setRatioAdjustion(ImageConvert.KeepRatioType.BaseOnHeight); } else if (getMessage("BaseOnLarger").equals(s)) { - attributes.setRatioAdjustion(ImageConvertTools.KeepRatioType.BaseOnLarger); + attributes.setRatioAdjustion(ImageConvert.KeepRatioType.BaseOnLarger); } else if (getMessage("BaseOnSmaller").equals(s)) { - attributes.setRatioAdjustion(ImageConvertTools.KeepRatioType.BaseOnSmaller); + attributes.setRatioAdjustion(ImageConvert.KeepRatioType.BaseOnSmaller); } else { - attributes.setRatioAdjustion(ImageConvertTools.KeepRatioType.None); + attributes.setRatioAdjustion(ImageConvert.KeepRatioType.None); } } catch (Exception e) { logger.error(e.toString()); @@ -260,8 +254,8 @@ protected void checkRatio() { height = Integer.valueOf(heightInput.getText()); attributes.setTargetWidth(width); attributes.setTargetHeight(height); - int sourceX = values.getImageInfo().getWidth(); - int sourceY = values.getImageInfo().getHeight(); + int sourceX = (int) values.getImage().getWidth(); + int sourceY = (int) values.getImage().getHeight(); if (noRatio || !keepRatioCheck.isSelected() || sourceX <= 0 || sourceY <= 0) { return; } @@ -271,20 +265,20 @@ protected void checkRatio() { return; } switch (attributes.getRatioAdjustion()) { - case ImageConvertTools.KeepRatioType.BaseOnWidth: + case ImageConvert.KeepRatioType.BaseOnWidth: heightInput.setText(Math.round(width * sourceY / sourceX) + ""); break; - case ImageConvertTools.KeepRatioType.BaseOnHeight: + case ImageConvert.KeepRatioType.BaseOnHeight: widthInput.setText(Math.round(height * sourceX / sourceY) + ""); break; - case ImageConvertTools.KeepRatioType.BaseOnLarger: + case ImageConvert.KeepRatioType.BaseOnLarger: if (ratioX > ratioY) { heightInput.setText(Math.round(width * sourceY / sourceX) + ""); } else { widthInput.setText(Math.round(height * sourceX / sourceY) + ""); } break; - case ImageConvertTools.KeepRatioType.BaseOnSmaller: + case ImageConvert.KeepRatioType.BaseOnSmaller: if (ratioX > ratioY) { widthInput.setText(Math.round(height * sourceX / sourceY) + ""); } else { @@ -304,11 +298,11 @@ protected void checkRatio() { @FXML protected void setOriginalSize() { noRatio = true; - if (values.getImageInfo().getWidth() > 0) { - widthInput.setText(values.getImageInfo().getWidth() + ""); + if (values.getImage().getWidth() > 0) { + widthInput.setText((int) values.getImage().getWidth() + ""); } - if (values.getImageInfo().getHeight() > 0) { - heightInput.setText(values.getImageInfo().getHeight() + ""); + if (values.getImage().getHeight() > 0) { + heightInput.setText((int) values.getImage().getHeight() + ""); } noRatio = false; } @@ -348,7 +342,8 @@ public void handle(WindowEvent event) { } @FXML - protected void pixelsAction() { + @Override + public void okAction() { if (isScale) { setScale(); } else { @@ -363,7 +358,7 @@ protected void setScale() { task = new Task() { @Override protected Void call() throws Exception { - final Image newImage = FxmlImageTools.scaleImage(values.getCurrentImage(), values.getImageInfo().getImageFormat(), scale); + final Image newImage = ImageTools.scaleImage(values.getCurrentImage(), scale); if (task.isCancelled()) { return null; } @@ -376,6 +371,7 @@ public void run() { imageView.setImage(newImage); setImageChanged(true); setBottomLabel(); + popInformation(AppVaribles.getMessage("Successful"), 1500); } }); return null; @@ -394,7 +390,7 @@ protected void setPixels() { task = new Task() { @Override protected Void call() throws Exception { - final Image newImage = FxmlImageTools.scaleImage(values.getCurrentImage(), values.getImageInfo().getImageFormat(), width, height); + final Image newImage = ImageTools.scaleImage(values.getCurrentImage(), width, height); if (task.isCancelled()) { return null; } @@ -407,6 +403,7 @@ public void run() { imageView.setImage(newImage); setImageChanged(true); setBottomLabel(); + popInformation(AppVaribles.getMessage("Successful"), 1500); } }); return null; diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureTextController.java b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureTextController.java index 062ab038c..838c289ec 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureTextController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureTextController.java @@ -21,11 +21,11 @@ import javafx.scene.paint.Color; import javafx.scene.text.Font; import javafx.stage.Modality; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.CommonValues; -import mara.mybox.fxml.FxmlImageTools; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.value.CommonValues; +import mara.mybox.fxml.image.ImageTools; import mara.mybox.fxml.FxmlTools; import static mara.mybox.fxml.FxmlTools.badStyle; @@ -80,7 +80,8 @@ protected void initInterface() { super.initInterface(); isSettingValues = true; - if (CommonValues.NoAlphaImages.contains(values.getImageInfo().getImageFormat())) { + if (values.getImageInfo() != null + && CommonValues.NoAlphaImages.contains(values.getImageInfo().getImageFormat())) { waterTransparentBox.setDisable(true); waterTransparentBox.getSelectionModel().select("1.0"); } else { @@ -323,7 +324,7 @@ protected Void call() throws Exception { } else { font = new java.awt.Font(fontFamily, java.awt.Font.PLAIN, waterSize); } - final Image newImage = FxmlImageTools.addText(values.getCurrentImage(), waterInput.getText(), + final Image newImage = ImageTools.addText(values.getCurrentImage(), waterInput.getText(), font, waterColorPicker.getValue(), waterX, waterY, waterTransparent, waterShadow, waterAngle, outlineCheck.isSelected()); if (task.isCancelled()) { diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureTransformController.java b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureTransformController.java index 478543647..2e9344784 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureTransformController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureTransformController.java @@ -16,11 +16,11 @@ import javafx.scene.layout.HBox; import javafx.scene.text.Font; import javafx.stage.Modality; -import static mara.mybox.objects.AppVaribles.logger; -import static mara.mybox.objects.AppVaribles.getMessage; +import static mara.mybox.value.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.getMessage; import mara.mybox.fxml.FxmlTools; import static mara.mybox.fxml.FxmlTools.badStyle; -import mara.mybox.fxml.FxmlTransformTools; +import mara.mybox.fxml.image.FxmlTransformTools; /** * @Author Mara diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureViewController.java b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureViewController.java index 1aa3a2f67..f83f193a2 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageManufactureViewController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageManufactureViewController.java @@ -5,7 +5,7 @@ import javafx.fxml.FXML; import javafx.scene.control.Slider; import javafx.scene.control.TextField; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.logger; import mara.mybox.fxml.FxmlTools; import static mara.mybox.fxml.FxmlTools.badStyle; diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageMetaDataController.java b/MyBox/src/main/java/mara/mybox/controller/ImageMetaDataController.java index 53580071a..47838e698 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageMetaDataController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageMetaDataController.java @@ -9,8 +9,8 @@ import javafx.scene.control.TextArea; import javafx.scene.control.TextField; import javafx.scene.input.MouseEvent; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.ImageInformation; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.data.ImageInformation; /** * @Author Mara diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageSampleController.java b/MyBox/src/main/java/mara/mybox/controller/ImageSampleController.java index c5c476e48..b82c4d6de 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageSampleController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageSampleController.java @@ -10,10 +10,8 @@ import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.concurrent.Task; -import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.Cursor; -import javafx.scene.control.Button; import javafx.scene.control.CheckBox; import javafx.scene.control.ComboBox; import javafx.scene.control.Label; @@ -26,15 +24,15 @@ import javafx.scene.paint.Color; import javafx.stage.FileChooser; import javafx.stage.Modality; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.fxml.FxmlScopeTools; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.fxml.image.FxmlScopeTools; import static mara.mybox.fxml.FxmlTools.badStyle; -import mara.mybox.imagefile.ImageFileReaders; -import mara.mybox.imagefile.ImageFileWriters; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.IntRectangle; +import mara.mybox.image.file.ImageFileReaders; +import mara.mybox.image.file.ImageFileWriters; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.value.CommonValues; +import mara.mybox.data.IntRectangle; import mara.mybox.tools.FileTools; /** @@ -47,15 +45,12 @@ public class ImageSampleController extends ImageViewerController { private double scale; private int sampleWidth, sampleHeight; - private boolean isSettingValues; @FXML private ToolBar opBar; @FXML private HBox cropBox, sampleBox, showBox; @FXML - private Button saveButton; - @FXML private CheckBox viewCheck; @FXML private ComboBox widthBox, heightBox; @@ -177,8 +172,8 @@ private void checkSample() { getMessage("ImageSize") + ": " + imageInformation.getWidth() + "x" + imageInformation.getHeight() + " " + getMessage("SampledSize") + ": " - + (int) ((cropRightX - cropLeftX) / sampleWidth) - + "x" + (int) ((cropRightY - cropLeftY) / sampleHeight)); + + (int) ((cropRightX - cropLeftX + 1) / sampleWidth) + + "x" + (int) ((cropRightY - cropLeftY + 1) / sampleHeight)); } } @@ -215,7 +210,7 @@ private void checkCropValues() { try { cropRightX = Integer.valueOf(cropRightXInput.getText()); - if (cropRightX >= 0 && cropRightX <= imageInformation.getWidth()) { + if (cropRightX >= 0 && cropRightX < imageInformation.getWidth()) { cropRightXInput.setStyle(null); } else { cropRightXInput.setStyle(badStyle); @@ -263,14 +258,18 @@ private void indicateCropScope() { @Override protected Void call() throws Exception { try { - int lineWidth = 1; - if (image.getWidth() >= 200) { - lineWidth = (int) image.getWidth() / 200; + final Image newImage; + if (isWholeImage(image)) { + newImage = image; + } else { + int lineWidth = 1; + if (image.getWidth() >= 200) { + lineWidth = (int) image.getWidth() / 200; + } + newImage = FxmlScopeTools.indicateRectangle(image, Color.RED, lineWidth, + new IntRectangle((int) (cropLeftX / scale), (int) (cropLeftY / scale), + (int) (cropRightX / scale), (int) (cropRightY / scale))); } - final Image newImage = FxmlScopeTools.indicateRectangle(image, - Color.RED, lineWidth, - new IntRectangle((int) (cropLeftX / scale), (int) (cropLeftY / scale), - (int) (cropRightX / scale), (int) (cropRightY / scale))); if (task.isCancelled()) { return null; } @@ -278,7 +277,7 @@ protected Void call() throws Exception { @Override public void run() { imageView.setImage(newImage); -// popInformation(AppVaribles.getMessage("CropComments")); +// infoAction(AppVaribles.getMessage("CropComments")); } }); } catch (Exception e) { @@ -388,24 +387,28 @@ public void clickImage(MouseEvent event) { } @FXML - private void allAction(ActionEvent event) { + @Override + public void selectAllAction() { isSettingValues = true; cropLeftXInput.setText("0"); cropLeftYInput.setText("0"); - cropRightXInput.setText(imageInformation.getWidth() + ""); - cropRightYInput.setText(imageInformation.getHeight() + ""); + cropRightXInput.setText((imageInformation.getWidth() - 1) + ""); + cropRightYInput.setText((imageInformation.getHeight() - 1) + ""); isSettingValues = false; checkCropValues(); } @FXML - public void saveAction(ActionEvent event) { + @Override + public void saveAction() { if (image == null || sampleWidth < 1 || sampleHeight < 1) { return; } final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(targetPathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(targetPathKey); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } fileChooser.getExtensionFilters().addAll(fileExtensionFilter); final File file = fileChooser.showSaveDialog(getMyStage()); if (file == null) { diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageSourcesController.java b/MyBox/src/main/java/mara/mybox/controller/ImageSourcesController.java index 7b7a366b8..ee490e0c3 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageSourcesController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageSourcesController.java @@ -38,13 +38,13 @@ import javafx.stage.FileChooser; import javafx.stage.Modality; import javafx.util.Callback; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.imagefile.ImageFileReaders; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.CommonValues; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.ImageFileInformation; -import mara.mybox.objects.ImageInformation; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.image.file.ImageFileReaders; +import mara.mybox.value.AppVaribles; +import mara.mybox.value.CommonValues; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.data.ImageFileInformation; +import mara.mybox.data.ImageInformation; import mara.mybox.tools.ValueTools; /** @@ -56,13 +56,13 @@ public class ImageSourcesController extends ImageViewerController { protected File targetFile; - protected boolean isSettingValues, isOpenning; + protected boolean isOpenning; protected SimpleBooleanProperty changed, hasSampled; protected ObservableList sourceImages = FXCollections.observableArrayList(); @FXML - protected Button saveButton, deleteButton, saveAsButton, insertButton, viewButton, clearButton; + protected Button saveAsButton, insertButton, viewButton, clearButton; @FXML protected TableView sourceTable; @FXML @@ -229,8 +229,10 @@ protected void createAction(ActionEvent event) { } sourceImages.clear(); final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(sourcePathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(sourcePathKey); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } fileChooser.getExtensionFilters().addAll(fileExtensionFilter); final File file = fileChooser.showSaveDialog(getMyStage()); if (file == null) { @@ -255,8 +257,10 @@ protected void openAction(ActionEvent event) { return; } final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(sourcePathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(sourcePathKey); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } fileChooser.getExtensionFilters().addAll(fileExtensionFilter); final File file = fileChooser.showOpenDialog(getMyStage()); if (file == null) { @@ -299,6 +303,7 @@ protected boolean checkSaving() { Alert alert = new Alert(Alert.AlertType.CONFIRMATION); alert.setTitle(getMyStage().getTitle()); alert.setContentText(AppVaribles.getMessage("ImageChanged")); + alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); ButtonType buttonSave = new ButtonType(AppVaribles.getMessage("Save")); ButtonType buttonNotSave = new ButtonType(AppVaribles.getMessage("NotSave")); ButtonType buttonCancel = new ButtonType(AppVaribles.getMessage("Cancel")); @@ -350,11 +355,14 @@ protected boolean hasSampled() { } @FXML - protected void saveAction() { + @Override + public void saveAction() { if (targetFile == null) { final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(targetPathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(targetPathKey); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } fileChooser.getExtensionFilters().addAll(fileExtensionFilter); final File file = fileChooser.showSaveDialog(getMyStage()); if (file == null) { @@ -373,8 +381,10 @@ protected void saveAsAction() { return; } final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(targetPathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(targetPathKey); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } fileChooser.getExtensionFilters().addAll(fileExtensionFilter); final File file = fileChooser.showSaveDialog(getMyStage()); if (file == null) { @@ -432,8 +442,10 @@ protected void insertAction(ActionEvent event) { protected void addAction(int index) { try { final FileChooser fileChooser = new FileChooser(); - File defaultPath = new File(AppVaribles.getUserConfigPath(sourcePathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(defaultPath); + File defaultPath = AppVaribles.getUserConfigPath(sourcePathKey); + if (defaultPath.exists()) { + fileChooser.setInitialDirectory(defaultPath); + } fileChooser.getExtensionFilters().addAll(CommonValues.ImageExtensionFilter); List files = fileChooser.showOpenMultipleDialog(getMyStage()); @@ -547,7 +559,8 @@ protected void loadFile(final File file, List infos) { } @FXML - protected void deleteAction(ActionEvent event) { + @Override + public void deleteAction() { List selected = new ArrayList<>(); selected.addAll(sourceTable.getSelectionModel().getSelectedIndices()); if (selected.isEmpty()) { @@ -618,7 +631,8 @@ protected void downAction(ActionEvent event) { } @FXML - protected void showInfo() { + @Override + public void infoAction() { showImageInformation(sourceTable.getSelectionModel().getSelectedItem()); } diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageSplitController.java b/MyBox/src/main/java/mara/mybox/controller/ImageSplitController.java index 038334c1a..4e3337cc5 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageSplitController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageSplitController.java @@ -39,19 +39,19 @@ import javafx.scene.text.Font; import javafx.stage.FileChooser; import javafx.stage.Modality; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.image.ImageConvertTools; -import mara.mybox.imagefile.ImageFileWriters; -import mara.mybox.objects.AppVaribles; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.image.ImageConvert; +import mara.mybox.image.file.ImageFileWriters; +import mara.mybox.value.AppVaribles; import mara.mybox.fxml.FxmlTools; -import mara.mybox.fxml.FxmlImageTools; +import mara.mybox.fxml.image.ImageTools; import static mara.mybox.fxml.FxmlTools.badStyle; -import mara.mybox.image.ImageValueTools; -import mara.mybox.imagefile.ImageFileReaders; -import mara.mybox.imagefile.ImageTiffFile; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.ImageAttributes; +import mara.mybox.image.ImageValue; +import mara.mybox.image.file.ImageFileReaders; +import mara.mybox.image.file.ImageTiffFile; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.value.CommonValues; +import mara.mybox.data.ImageAttributes; import mara.mybox.tools.FileTools; import mara.mybox.tools.PdfTools; import mara.mybox.tools.PdfTools.PdfImageFormat; @@ -69,7 +69,7 @@ public class ImageSplitController extends ImageViewerController { private List rows, cols; private int rowsNumber, colsNumber, width, height, marginSize, pageWidth, pageHeight, jpegQuality, threshold; - private boolean isImageSize, isSettingValues; + private boolean isImageSize; private double scale; private PdfImageFormat pdfFormat; protected SimpleBooleanProperty splitValid; @@ -86,12 +86,12 @@ public static enum SplitMethod { @FXML private ToggleGroup splitGroup, sizeGroup, formatGroup, colorGroup, compressionGroup, binaryGroup; @FXML - private Button imagesButton, tiffButton, pdfButton, okButton; + private Button imagesButton, tiffButton, pdfButton; @FXML private TextField rowsInput, colsInput, customizedRowsInput, customizedColsInput, customWidthInput, customHeightInput, authorInput, pdfThresholdInput, headerInput, tiffThresholdInput; @FXML - private CheckBox displaySizeCheck, pageNumberCheck; + private CheckBox displaySizeCheck, pageNumberCheck, pdfDitherCheck, tiffDitherCheck; @FXML private ComboBox lineWidthBox; @FXML @@ -434,6 +434,8 @@ public void changed(ObservableValue observable, } }); + FxmlTools.setComments(tiffDitherCheck, new Tooltip(getMessage("DitherComments"))); + } catch (Exception e) { logger.error(e.toString()); } @@ -468,7 +470,7 @@ protected void setCompressionTypes() { compressionBox.getChildren().clear(); compressionGroup = new ToggleGroup(); String[] compressionTypes - = ImageValueTools.getCompressionTypes("tif", attributes.getColorSpace()); + = ImageValue.getCompressionTypes("tif", attributes.getColorSpace()); for (String ctype : compressionTypes) { if (ctype.equals("ZLib")) { // This type looks not work for mutiple frames tiff file continue; @@ -527,7 +529,7 @@ protected void checkTiffThreshold() { return; } int inputValue = Integer.parseInt(tiffThresholdInput.getText()); - if (inputValue >= 0 && inputValue <= 100) { + if (inputValue >= 0 && inputValue <= 255) { attributes.setThreshold(inputValue); tiffThresholdInput.setStyle(null); } else { @@ -646,6 +648,8 @@ public void changed(ObservableValue observable, String oldValu }); checkPdfThreshold(); + FxmlTools.setComments(pdfDitherCheck, new Tooltip(getMessage("DitherComments"))); + MarginsBox.getItems().addAll(Arrays.asList("20", "10", "15", "5", "25", "30")); MarginsBox.valueProperty().addListener(new ChangeListener() { @Override @@ -877,7 +881,7 @@ private void checkPdfThreshold() { return; } threshold = Integer.valueOf(pdfThresholdInput.getText()); - if (threshold >= 0 && threshold <= 100) { + if (threshold >= 0 && threshold <= 255) { pdfThresholdInput.setStyle(null); } else { threshold = -1; @@ -949,7 +953,8 @@ protected void handleSampledImage() { } @FXML - private void okAction(ActionEvent event) { + @Override + public void okAction() { if (splitMethod == SplitMethod.ByNumber) { divideImageByNumber(); } else if (splitMethod == SplitMethod.BySize) { @@ -1127,7 +1132,7 @@ private void indicateSplit() { protected Void call() throws Exception { ValueTools.sortList(rows); ValueTools.sortList(cols); - final Image newImage = FxmlImageTools.indicateSplit(image, rows, cols, + final Image newImage = ImageTools.indicateSplit(image, rows, cols, lineColorPicker.getValue(), lineWidthBox.getValue(), displaySizeCheck.isSelected(), scale); if (task.isCancelled()) { @@ -1171,6 +1176,7 @@ private File validationBeforeSave(List ext, String alert.setTitle(getMyStage().getTitle()); alert.setContentText(AppVaribles.getMessage("SureSampled")); alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); + alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); ButtonType buttonSure = new ButtonType(AppVaribles.getMessage("Sure")); ButtonType buttonCancel = new ButtonType(AppVaribles.getMessage("Cancel")); alert.getButtonTypes().setAll(buttonSure, buttonCancel); @@ -1181,8 +1187,10 @@ private File validationBeforeSave(List ext, String } } final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(targetPathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(targetPathKey); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } fileChooser.getExtensionFilters().addAll(ext); if (diagTitle != null) { fileChooser.setTitle(diagTitle); @@ -1214,7 +1222,7 @@ protected Void call() throws Exception { final String filename = sourceFile.getAbsolutePath(); BufferedImage wholeSource = null; if (!imageInformation.isIsSampled()) { - wholeSource = FxmlImageTools.getBufferedImage(image); + wholeSource = ImageTools.getBufferedImage(image); } for (int i = 0; i < rows.size() - 1; i++) { if (task.isCancelled()) { @@ -1232,7 +1240,7 @@ protected Void call() throws Exception { if (imageInformation.isIsSampled()) { target = ImageFileReaders.readRectangle(sourceFormat, filename, x1, y1, x2, y2); } else { - target = ImageConvertTools.cropImage(wholeSource, x1, y1, x2, y2); + target = ImageConvert.cropImage(wholeSource, x1, y1, x2, y2); } String fileName = filePrefix + "_" + (rows.size() - 1) + "x" + (cols.size() - 1) + "_" @@ -1271,6 +1279,7 @@ private void saveAsPdfAction() { protected Void call() throws Exception { final String sourceFormat = imageInformation.getImageFormat(); final String sourcefile = sourceFile.getAbsolutePath(); + attributes.setIsDithering(pdfDitherCheck.isSelected()); ok = PdfTools.writeSplitImages(sourceFormat, sourcefile, imageInformation, rows, cols, attributes, targetFile, pdfFormat, fontBox.getSelectionModel().getSelectedItem(), authorInput.getText(), @@ -1316,6 +1325,7 @@ private void saveAsTiffAction(ActionEvent event) { protected Void call() throws Exception { final String sourceFormat = imageInformation.getImageFormat(); final String filename = sourceFile.getAbsolutePath(); + attributes.setIsDithering(tiffDitherCheck.isSelected()); ok = ImageTiffFile.writeSplitImages(sourceFormat, filename, imageInformation, rows, cols, attributes, targetFile); if (task.isCancelled()) { diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageStatisticController.java b/MyBox/src/main/java/mara/mybox/controller/ImageStatisticController.java new file mode 100644 index 000000000..52855f3d0 --- /dev/null +++ b/MyBox/src/main/java/mara/mybox/controller/ImageStatisticController.java @@ -0,0 +1,420 @@ +package mara.mybox.controller; + +import java.util.Arrays; +import java.util.List; +import javafx.application.Platform; +import javafx.beans.binding.Bindings; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.concurrent.Task; +import javafx.fxml.FXML; +import javafx.scene.chart.BarChart; +import javafx.scene.chart.NumberAxis; +import javafx.scene.chart.PieChart; +import javafx.scene.control.CheckBox; +import javafx.scene.control.ComboBox; +import javafx.scene.control.ContentDisplay; +import javafx.scene.control.Tab; +import javafx.scene.control.TabPane; +import javafx.scene.control.TableCell; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.control.ToolBar; +import javafx.scene.control.Tooltip; +import javafx.scene.control.cell.PropertyValueFactory; +import javafx.scene.paint.Color; +import javafx.scene.shape.Rectangle; +import javafx.scene.text.Font; +import javafx.scene.text.Text; +import javafx.stage.Modality; +import javafx.util.Callback; +import mara.mybox.fxml.FxmlTools; +import mara.mybox.fxml.image.ImageQuantization; +import mara.mybox.image.ImageColor; +import mara.mybox.image.ImageQuantization.QuantizationAlgorithm; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.getMessage; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.data.IntStatistic; + +/** + * @Author Mara + * @CreateDate 2018-10-12 + * @Description + * @License Apache License Version 2.0 + */ +public class ImageStatisticController extends ImageViewerController { + + final private String ImageStatisticHueStages, ImageStatisticSaturationStages, + ImageStatisticBrightnessStages, ImageStatisticDataNumber; + private int paletteSize; + + protected ObservableList colorList = FXCollections.observableArrayList(); + protected ObservableList colorSummaryList = FXCollections.observableArrayList(); + protected ObservableList greyList = FXCollections.observableArrayList(); + protected ObservableList redList = FXCollections.observableArrayList(); + protected ObservableList blueList = FXCollections.observableArrayList(); + protected ObservableList greenList = FXCollections.observableArrayList(); + protected ObservableList hueList = FXCollections.observableArrayList(); + protected ObservableList saturationList = FXCollections.observableArrayList(); + protected ObservableList brightnessList = FXCollections.observableArrayList(); + protected ObservableList opacityList = FXCollections.observableArrayList(); + + @FXML + protected TabPane tabPane; + @FXML + protected Tab imageTab, histogramTab; + @FXML + protected BarChart greyHistogram, redHistogram, blueHistogram, greenHistogram, + opacityHistogram, hueHistogram, saturationHistogram, brightnessHistogram; + @FXML + protected PieChart colorPie; + @FXML + protected ComboBox paletteBox, algorithmBox; + @FXML + protected NumberAxis grayY; + @FXML + private TableView colorTable, colorSummaryTable, greyTable, redTable, blueTable, greenTable, + hueTable, saturationTable, brightnessTable, opacityTable; + @FXML + private TableColumn colorSummaryNameColumn, + greyNameColumn, + redValueColumn, redNameColumn, + blueValueColumn, blueNameColumn, greenValueColumn, greenNameColumn, hueValueColumn, hueNameColumn, + saturationValueColumn, saturationNameColumn, brightnessValueColumn, brightnessNameColumn, + opacityValueColumn, opacityNameColumn; + @FXML + private TableColumn colorSequenceColumn, colorValueColumn, colorNumberColumn, colorShowcaseColumn, + colorSummaryValueColumn, colorSummaryShowcaseColumn, colorSummaryNumberColumn, + greyValueColumn, greyNumberColumn, greyShowcaseColumn, + redNumberColumn, blueNumberColumn, greenNumberColumn, + hueNumberColumn, saturationNumberColumn, brightnessNumberColumn, opacityNumberColumn; + @FXML + private TableColumn colorPercentageColumn, colorSummaryPercentageColumn, + greyPercentageColumn; + @FXML + private CheckBox ditheringCheck; + @FXML + private ToolBar colorBar; + + public ImageStatisticController() { + ImageStatisticHueStages = "ImageStatisticHueStages"; + ImageStatisticSaturationStages = "ImageStatisticSaturationStages"; + ImageStatisticBrightnessStages = "ImageStatisticBrightnessStages"; + ImageStatisticDataNumber = "ImageStatisticDataNumber"; + } + + @Override + protected void initializeNext2() { + try { + tabPane.disableProperty().bind( + Bindings.isNull(imageView.imageProperty()) + ); + imageView.requestFocus(); + + initColorTab(); + initGreyTab(); + + } catch (Exception e) { + logger.error(e.toString()); + } + } + + private void initColorTab() { + + Tooltip tips = new Tooltip(getMessage("QuantizationComments")); + tips.setFont(new Font(16)); + FxmlTools.setComments(colorBar, tips); + + FxmlTools.setComments(ditheringCheck, new Tooltip(getMessage("DitherComments"))); + + colorTable.setItems(colorList); + colorValueColumn.setCellValueFactory(new PropertyValueFactory("value")); +// colorValueColumn.setCellFactory(new Callback, TableCell>() { +// @Override +// public TableCell call(TableColumn param) { +// String name = (String) param.getColumns().get(0); +// return new ValueCell(); +// } +// }); + colorShowcaseColumn.setCellValueFactory(new PropertyValueFactory("value")); + colorShowcaseColumn.setCellFactory(new Callback, TableCell>() { + @Override + public TableCell call(TableColumn param) { + return new ShowcaseCell(); + } + }); + colorNumberColumn.setCellValueFactory(new PropertyValueFactory("number")); + colorSequenceColumn.setCellValueFactory(new PropertyValueFactory("value2")); + colorPercentageColumn.setCellValueFactory(new PropertyValueFactory("percentage")); + + colorSummaryTable.setItems(colorSummaryList); + colorSummaryValueColumn.setCellValueFactory(new PropertyValueFactory("value")); + colorSummaryValueColumn.setCellFactory(new Callback, TableCell>() { + @Override + public TableCell call(TableColumn param) { + return new ValueCell(); + } + }); + colorSummaryShowcaseColumn.setCellValueFactory(new PropertyValueFactory("value")); + colorSummaryShowcaseColumn.setCellFactory(new Callback, TableCell>() { + @Override + public TableCell call(TableColumn param) { + return new ShowcaseCell(); + } + }); + colorSummaryNameColumn.setCellValueFactory(new PropertyValueFactory("name")); + colorSummaryNameColumn.setCellFactory(new Callback, TableCell>() { + @Override + public TableCell call(TableColumn param) { + return new NameCell(); + } + }); + colorSummaryNumberColumn.setCellValueFactory(new PropertyValueFactory("number")); + colorSummaryPercentageColumn.setCellValueFactory(new PropertyValueFactory("percentage")); + + List aList = Arrays.asList( + getMessage("RGBUniformQuantization"), getMessage("HSBUniformQuantization")); + algorithmBox.getItems().addAll(aList); + algorithmBox.getSelectionModel().select(getMessage("RGBUniformQuantization")); + + List paletteList = Arrays.asList( + "512", "64", "8", "4096", "216", "343", "27", "125", "1000", "729", "1728", "8000"); + paletteBox.getItems().addAll(paletteList); + paletteBox.valueProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue ov, String oldValue, String newValue) { + try { + paletteSize = Integer.valueOf(newValue); + } catch (Exception e) { + } + } + }); + paletteBox.getSelectionModel().select("512"); + + } + + private void initGreyTab() { + greyTable.setItems(greyList); + greyValueColumn.setCellValueFactory(new PropertyValueFactory("value")); + greyValueColumn.setCellFactory(new Callback, TableCell>() { + @Override + public TableCell call(TableColumn param) { + return new ValueCell(); + } + }); + greyShowcaseColumn.setCellValueFactory(new PropertyValueFactory("value")); + greyShowcaseColumn.setCellFactory(new Callback, TableCell>() { + @Override + public TableCell call(TableColumn param) { + return new ShowcaseCell(); + } + }); + greyNameColumn.setCellValueFactory(new PropertyValueFactory("name")); + greyNameColumn.setCellFactory(new Callback, TableCell>() { + @Override + public TableCell call(TableColumn param) { + return new NameCell(); + } + }); + greyNumberColumn.setCellValueFactory(new PropertyValueFactory("number")); + greyPercentageColumn.setCellValueFactory(new PropertyValueFactory("percentage")); + + } + + private class ValueCell extends TableCell { + + @Override + protected void updateItem(final Integer item, boolean empty) { + super.updateItem(item, empty); + if (item == null || item < 0 || empty) { + setText(""); + } else { + if (item > 255) { + setText(ImageColor.pixel2hex(item)); + } else { + setText(item + ""); + } + } + } + } + + private class ShowcaseCell extends TableCell { + + private final Rectangle rectangle; + + { + setContentDisplay(ContentDisplay.GRAPHIC_ONLY); + rectangle = new Rectangle(30, 20); + } + + @Override + protected void updateItem(final Integer item, boolean empty) { + super.updateItem(item, empty); + if (item == null || item < 0 || empty) { + setGraphic(null); + } else { + if (item > 255) { + rectangle.setFill(ImageColor.converColor(new java.awt.Color(item))); + setGraphic(rectangle); + } else { + double grey = item / 255.0; + rectangle.setFill(new Color(grey, grey, grey, 1.0)); + setGraphic(rectangle); + } + + } + } + + } + + private class NameCell extends TableCell { + + final Text text = new Text(); + + @Override + protected void updateItem(final String item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty) { + text.setText(AppVaribles.getMessage(item)); + setGraphic(text); + } + } + } + + @Override + public void afterImageLoaded() { + try { + super.afterImageLoaded(); + if (image == null) { + return; + } + makeStatistic(); + } catch (Exception e) { + logger.error(e.toString()); + imageView.setImage(null); + alertInformation(AppVaribles.getMessage("NotSupported")); + } + } + + @FXML + public void colorAction() { + makeStatistic(); + } + + // https://stackoverflow.com/questions/15219334/javafx-change-piechart-color + private void makeStatistic() { + QuantizationAlgorithm algorithm; + switch (algorithmBox.getSelectionModel().getSelectedIndex()) { + case 0: + algorithm = QuantizationAlgorithm.RGB_Uniform; + break; + case 1: + algorithm = QuantizationAlgorithm.HSB_Uniform; + break; + case 4: + algorithm = QuantizationAlgorithm.Statistic; + break; + case 5: + algorithm = QuantizationAlgorithm.kMeansClustering; + break; + case 6: + algorithm = QuantizationAlgorithm.ANN; + break; + default: + return; + } + int channelSize = (int) Math.round(Math.pow(paletteSize, 1.0 / 3.0)); + final ImageQuantization quantization = new ImageQuantization(image); + quantization.set(algorithm, channelSize); + quantization.setIsDithering(ditheringCheck.isSelected()); + + colorList.clear(); + colorSummaryList.clear(); + greyList.clear(); + redList.clear(); + blueList.clear(); + opacityList.clear(); + greenList.clear(); + hueList.clear(); + saturationList.clear(); + brightnessList.clear(); + + colorPie.getData().clear(); + greyHistogram.getData().clear(); + redHistogram.getData().clear(); + blueHistogram.getData().clear(); + opacityHistogram.getData().clear(); + greenHistogram.getData().clear(); + hueHistogram.getData().clear(); + saturationHistogram.getData().clear(); + brightnessHistogram.getData().clear(); + + task = new Task() { + @Override + protected Void call() throws Exception { + try { +// ImageStatistic statistic = new ImageStatistic(SwingFXUtils.fromFXImage(image, null), quantization); +// final Map statisticMap = statistic.statistic(); +// if (task.isCancelled() || statisticMap == null) { +// return null; +// } + Platform.runLater(new Runnable() { + @Override + public void run() { +// Map statistic = (Map) statisticMap.get("colorQuantization"); +// colorList.addAll((List) statistic.get("data")); +// ObservableList pieChartData = FXCollections.observableArrayList(); +// for (int i = 0; i < colorList.size(); i++) { +// IntStatistic s = colorList.get(i); +// if (s.getPercentage() < 1) { +// break; +// } +// pieChartData.add(new PieChart.Data(s.getPercentage() + "% " +// + ImageColor.pixel2hex(colorList.get(i).getValue()), s.getNumber())); +// } +// colorPie.getData().addAll(pieChartData); +// for (int i = 0; i < pieChartData.size(); i++) { +// PieChart.Data d = pieChartData.get(i); +// d.getNode().setStyle("-fx-pie-color: " + ImageColor.pixel2hex(colorList.get(i).getValue()) + ";" +// ); +// } // Must set colors after chart generated +// colorSummaryList.add((IntStatistic) statistic.get("size")); +// colorSummaryList.add((IntStatistic) statistic.get("sum")); +// colorSummaryList.add((IntStatistic) statistic.get("mode")); +// colorSummaryList.add((IntStatistic) statistic.get("median")); +// colorSummaryList.add((IntStatistic) statistic.get("mean")); +// colorSummaryList.add((IntStatistic) statistic.get("variance")); +// +// statistic = (Map) statisticMap.get("grey"); +// greyList.addAll((List) statistic.get("data")); +// XYChart.Series series = new XYChart.Series(); +// for (int i = 0; i < greyList.size(); i++) { +// IntStatistic s = greyList.get(i); +// series.getData().add(new XYChart.Data(s.getValue() + "", s.getNumber())); +// } +// greyHistogram.getData().addAll(series); +// IntStatistic.setDesc(greyList); // Must sort after historgram generated + +// greyList.add(0, (IntStatistic) statistic.get("maximum")); +// greyList.add(0, (IntStatistic) statistic.get("minimum")); +// greyList.add(0, (IntStatistic) statistic.get("median")); +// greyList.add(0, (IntStatistic) statistic.get("average")); +// greyList.add(0, (IntStatistic) statistic.get("sum")); + } + }); + } catch (Exception e) { + logger.debug(e.toString()); + } + return null; + } + }; + openHandlingStage(task, Modality.WINDOW_MODAL); + Thread thread = new Thread(task); + thread.setDaemon(true); + thread.start(); + } + +} diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageTiffEditerController.java b/MyBox/src/main/java/mara/mybox/controller/ImageTiffEditerController.java index 5c1f5e1c5..c515a3bcb 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageTiffEditerController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageTiffEditerController.java @@ -13,14 +13,14 @@ import javafx.scene.control.ToggleGroup; import javafx.scene.layout.HBox; import javafx.stage.Modality; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.logger; import static mara.mybox.fxml.FxmlTools.badStyle; -import mara.mybox.image.ImageValueTools; -import mara.mybox.imagefile.ImageTiffFile; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.ImageAttributes; +import mara.mybox.image.ImageValue; +import mara.mybox.image.file.ImageTiffFile; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.value.CommonValues; +import mara.mybox.data.ImageAttributes; import org.apache.pdfbox.rendering.ImageType; /** @@ -126,7 +126,7 @@ protected void setCompressionTypes() { compressionBox.getChildren().clear(); compressionGroup = new ToggleGroup(); String[] compressionTypes - = ImageValueTools.getCompressionTypes("tif", attributes.getColorSpace()); + = ImageValue.getCompressionTypes("tif", attributes.getColorSpace()); for (String ctype : compressionTypes) { if (ctype.equals("ZLib")) { // This type looks not work for mutiple frames tiff file continue; @@ -185,7 +185,7 @@ protected void checkThreshold() { return; } int inputValue = Integer.parseInt(thresholdInput.getText()); - if (inputValue >= 0 && inputValue <= 100) { + if (inputValue >= 0 && inputValue <= 255) { attributes.setThreshold(inputValue); thresholdInput.setStyle(null); } else { diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageViewerController.java b/MyBox/src/main/java/mara/mybox/controller/ImageViewerController.java index ce5bdb6b9..62ac839a4 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageViewerController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageViewerController.java @@ -1,53 +1,74 @@ package mara.mybox.controller; +import com.sun.javafx.charts.Legend; +import mara.mybox.fxml.FxmlStage; import java.awt.image.BufferedImage; import java.io.File; import java.text.MessageFormat; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Optional; import javafx.application.Platform; import javafx.beans.binding.Bindings; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; import javafx.concurrent.Task; +import javafx.embed.swing.SwingFXUtils; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.scene.Cursor; +import javafx.scene.Node; +import javafx.scene.chart.BarChart; +import javafx.scene.chart.XYChart; import javafx.scene.control.Alert; import javafx.scene.control.Button; import javafx.scene.control.ButtonType; +import javafx.scene.control.CheckBox; +import javafx.scene.control.ContentDisplay; import javafx.scene.control.Hyperlink; import javafx.scene.control.Label; import javafx.scene.control.RadioButton; +import javafx.scene.control.SplitPane; +import javafx.scene.control.TableCell; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; import javafx.scene.control.TextField; import javafx.scene.control.ToggleGroup; import javafx.scene.control.ToolBar; -import javafx.scene.control.Tooltip; +import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.image.Image; import javafx.scene.input.Clipboard; import javafx.scene.input.ClipboardContent; -import javafx.scene.input.KeyEvent; import javafx.scene.input.MouseButton; import javafx.scene.input.MouseEvent; import javafx.scene.layout.HBox; import javafx.scene.layout.Region; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; -import javafx.scene.text.Font; +import javafx.scene.shape.Rectangle; +import javafx.scene.text.Text; import javafx.stage.FileChooser; import javafx.stage.Modality; -import mara.mybox.fxml.FxmlImageTools; -import mara.mybox.fxml.FxmlScopeTools; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.CommonValues; +import javafx.util.Callback; +import mara.mybox.fxml.image.ImageTools; +import mara.mybox.fxml.image.FxmlScopeTools; +import mara.mybox.value.AppVaribles; +import mara.mybox.value.CommonValues; import mara.mybox.tools.FileTools; import mara.mybox.fxml.FxmlTools; -import mara.mybox.imagefile.ImageFileWriters; -import static mara.mybox.objects.AppVaribles.getMessage; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.IntRectangle; +import mara.mybox.image.file.ImageFileWriters; +import mara.mybox.data.ImageFileInformation; +import mara.mybox.data.IntRectangle; +import mara.mybox.data.IntStatistic; +import mara.mybox.fxml.FxmlColor; +import mara.mybox.image.ImageStatistic; +import static mara.mybox.value.AppVaribles.getMessage; +import static mara.mybox.value.AppVaribles.logger; /** * @Author Mara @@ -57,89 +78,181 @@ */ public class ImageViewerController extends ImageBaseController { + final protected String ConfirmDeleteKey, OpenAfterSaveKey, SelectKey; + protected double mouseX, mouseY; protected int xZoomStep = 50, yZoomStep = 50; protected int currentAngle = 0, rotateAngle = 90; protected File nextFile, previousFile; protected int cropLeftX, cropLeftY, cropRightX, cropRightY; + protected ObservableList statisticList = FXCollections.observableArrayList(); + protected Map colorTable; + @FXML protected TextField imageFile; @FXML - protected HBox sourceBox, opeBox; + protected HBox operation1Box, operation2Box, operation3Box, navBox; @FXML protected VBox contentBox; @FXML - protected Button iButton, mButton, gButton, pButton, inButton, outButton, lButton, rButton, - previousButton, nextButton, wButton, oButton, - tButton, sButton, mrButton, mlButton, upButton, downButton, infoButton, metaButton, - cropButton, selectAllButton, copySelectionButton; - @FXML - protected ToolBar toolbar, navBar, infoBar, selectionBar, cropBar; + protected Button upButton, downButton, renameButton, metaButton, manufactureButton, statisticButton; @FXML protected ToggleGroup sortGroup; + @FXML + protected CheckBox cropCheck, deleteConfirmCheck, openSaveCheck; + @FXML + protected SplitPane splitPane; + @FXML + protected CheckBox dataCheck, greyHistCheck, redHistCheck, greenHistCheck, blueHistCheck, alphaHistCheck, + hueHistCheck, saturationHistCheck, brightnessHistCheck; + @FXML + protected SplitPane dataPane; + @FXML + protected TableView dataTable; + @FXML + protected TableColumn colorColumn; + @FXML + protected TableColumn meanColumn, varianceColumn, + skewnessColumn, maximumColumn, minimumColumn, modeColumn; + @FXML + protected BarChart histogramChart; + @FXML + protected ToolBar manuBar; public ImageViewerController() { - + ConfirmDeleteKey = "ImageConfirmDeleteKey"; + OpenAfterSaveKey = "ImageOpenAfterSaveKey"; + SelectKey = "ImageSelectKey"; + TipsLabelKey = "ImageViewerTips"; } @Override protected void initializeNext() { try { - if (imageView != null) { - if (toolbar != null) { - toolbar.disableProperty().bind( - Bindings.isNull(imageView.imageProperty()) - ); - } + initOperation1Box(); + initOperation2Box(); + initOperation3Box(); + initImageView(); + initDataPane(); + initializeNext2(); + } catch (Exception e) { + logger.error(e.toString()); + } + } - if (opeBox != null) { - opeBox.disableProperty().bind( - Bindings.isNull(imageView.imageProperty()) - ); + protected void initOperation1Box() { + if (operation1Box != null) { + operation1Box.disableProperty().bind( + Bindings.isNull(imageView.imageProperty()) + ); + } + + if (openSaveCheck != null) { + openSaveCheck.selectedProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue ov, Boolean oldValue, Boolean newValue) { + AppVaribles.setUserConfigValue(OpenAfterSaveKey, openSaveCheck.isSelected()); + } + }); + openSaveCheck.setSelected(AppVaribles.getUserConfigBoolean(OpenAfterSaveKey, false)); + } + if (deleteConfirmCheck != null) { + deleteConfirmCheck.selectedProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue ov, Boolean oldValue, Boolean newValue) { + AppVaribles.setUserConfigValue(ConfirmDeleteKey, deleteConfirmCheck.isSelected()); } + }); + deleteConfirmCheck.setSelected(AppVaribles.getUserConfigBoolean(ConfirmDeleteKey, true)); + } - if (scrollPane != null) { - imageView.fitHeightProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue ov, Number old_val, Number new_val) { - moveCenter(); - } - }); - scrollPane.heightProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue ov, Number old_val, Number new_val) { - if (Math.abs(imageView.getFitHeight() - old_val.doubleValue()) < 20) { - paneSize(); - } - moveCenter(); - } - }); - scrollPane.widthProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue ov, Number old_val, Number new_val) { - moveCenter(); - } - }); + } + + protected void initOperation2Box() { + + if (operation2Box != null) { + operation2Box.disableProperty().bind( + Bindings.isNull(imageView.imageProperty()) + ); + } + + if (cropCheck != null) { + cropCheck.selectedProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue ov, Boolean oldValue, Boolean newValue) { + AppVaribles.setUserConfigValue(SelectKey, cropCheck.isSelected()); + checkSelect(); } - } + }); + cropCheck.setSelected(AppVaribles.getUserConfigBoolean(SelectKey, true)); + checkSelect(); + } + + } + + protected void initOperation3Box() { + + if (navBox != null) { + navBox.setDisable(true); + } + + if (manufactureButton != null) { + manufactureButton.setDisable(true); + } + + if (manuBar != null) { + manuBar.disableProperty().bind( + Bindings.isNull(imageView.imageProperty()) + ); + } - if (copySelectionButton != null) { - Tooltip tips = new Tooltip("CTRL+c"); - tips.setFont(new Font(16)); - FxmlTools.quickTooltip(copySelectionButton, tips); + } + + protected void initImageView() { + if (imageView == null || scrollPane == null) { + return; + } + + imageView.fitHeightProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue ov, Number old_val, Number new_val) { + moveCenter(); } - if (cropButton != null) { - Tooltip tips = new Tooltip(getMessage("CropLabel")); - tips.setFont(new Font(16)); - FxmlTools.quickTooltip(cropButton, tips); + }); + scrollPane.heightProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue ov, Number old_val, Number new_val) { + if (Math.abs(imageView.getFitHeight() - old_val.doubleValue()) < 20) { + paneSize(); + } + moveCenter(); } + }); + scrollPane.widthProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue ov, Number old_val, Number new_val) { + moveCenter(); + } + }); - initializeNext2(); + } - } catch (Exception e) { - logger.error(e.toString()); + protected void checkSelect() { + if (image == null || cropCheck == null) { + return; + } + if (!cropCheck.isSelected()) { + imageView.setImage(image); + FxmlTools.removeTooltip(imageView); + bottomLabel.setText(""); + } else { + selectAllAction(); + + bottomLabel.setText(getMessage("CropLabel")); } + selectAllButton.setDisable(!cropCheck.isSelected()); + } public void moveCenter() { @@ -154,6 +267,381 @@ public void moveCenter() { } } + protected void initDataPane() { + try { + if (dataCheck == null || dataPane == null) { + return; + } + splitPane.disableProperty().bind( + Bindings.isNull(imageView.imageProperty()) + ); + + dataCheck.selectedProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue ov, Boolean old_val, Boolean new_val) { + if (isSettingValues) { + return; + } + loadDataBox(); + AppVaribles.setUserConfigValue("ImageDataShow", new_val); + } + }); + isSettingValues = true; + dataCheck.setSelected(AppVaribles.getUserConfigBoolean("ImageDataShow", true)); + isSettingValues = false; + loadDataBox(); + + dataTable.setItems(statisticList); + colorColumn.setCellValueFactory(new PropertyValueFactory("name")); + colorColumn.setCellFactory(new Callback, TableCell>() { + @Override + public TableCell call(TableColumn param) { + return new NameCell(); + } + }); + meanColumn.setCellValueFactory(new PropertyValueFactory("mean")); + meanColumn.setCellFactory(new Callback, TableCell>() { + @Override + public TableCell call(TableColumn param) { + return new ColorCell(); + } + }); + varianceColumn.setCellValueFactory(new PropertyValueFactory("variance")); + skewnessColumn.setCellValueFactory(new PropertyValueFactory("skewness")); + maximumColumn.setCellValueFactory(new PropertyValueFactory("maximum")); + maximumColumn.setCellFactory(new Callback, TableCell>() { + @Override + public TableCell call(TableColumn param) { + return new ColorCell(); + } + }); + minimumColumn.setCellValueFactory(new PropertyValueFactory("minimum")); + minimumColumn.setCellFactory(new Callback, TableCell>() { + @Override + public TableCell call(TableColumn param) { + return new ColorCell(); + } + }); + modeColumn.setCellValueFactory(new PropertyValueFactory("mode")); + modeColumn.setCellFactory(new Callback, TableCell>() { + @Override + public TableCell call(TableColumn param) { + return new ColorCell(); + } + }); + + colorTable = new HashMap<>(); + colorTable.put(AppVaribles.getMessage("Red"), Color.RED); + colorTable.put(AppVaribles.getMessage("Green"), Color.GREEN); + colorTable.put(AppVaribles.getMessage("Blue"), Color.BLUE); + colorTable.put(AppVaribles.getMessage("Alpha"), Color.CORNFLOWERBLUE); + colorTable.put(AppVaribles.getMessage("Hue"), Color.MEDIUMVIOLETRED); + colorTable.put(AppVaribles.getMessage("Brightness"), Color.GOLD); + colorTable.put(AppVaribles.getMessage("Saturation"), Color.MEDIUMAQUAMARINE); + colorTable.put(AppVaribles.getMessage("Gray"), Color.GRAY); + + } catch (Exception e) { + logger.error(e.toString()); + } + } + + private class NameCell extends TableCell { + + final Text text = new Text(); + + @Override + protected void updateItem(final String item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty) { + text.setText(AppVaribles.getMessage(item)); + setGraphic(text); + } + } + } + + private class ColorCell extends TableCell { + + private final Rectangle rectangle; + + { + setContentDisplay(ContentDisplay.LEFT); + rectangle = new Rectangle(30, 20); + } + private Color color; + + @Override + protected void updateItem(final Integer item, boolean empty) { + super.updateItem(item, empty); + if (item == null || item < 0 || empty) { + setGraphic(null); + } else { + IntStatistic row = getTableView().getItems().get(getTableRow().getIndex()); + + switch (row.getName()) { + case "Red": + color = new Color(item / 255.0, 0, 0, 1); + break; + case "Green": + color = new Color(0, item / 255.0, 0, 1); + break; + case "Blue": + color = new Color(0, 0, item / 255.0, 1); + break; + case "Alpha": + color = new Color(1, 1, 1, item / 255.0); + break; + case "Grey": + double c = item / 255.0; + color = new Color(c, c, c, 1); + break; + case "Hue": + color = Color.hsb(item, 1, 1); + break; + case "Saturation": + color = Color.hsb(66, item / 100.0, 1); + break; + case "Brightness": + color = Color.hsb(66, 1, item / 100.0); + break; + default: + color = null; + break; + } + if (color != null) { + rectangle.setFill(color); + setGraphic(rectangle); + } + setText(item + ""); + + } + } + + } + + protected void loadDataBox() { + try { + if (dataCheck == null) { + return; + } + if (dataCheck.isSelected()) { + + if (!splitPane.getItems().contains(dataPane)) { + splitPane.getItems().add(0, dataPane); + } + if (imageData != null) { + showData(); + } else { + loadData(); + } + + } else { + + if (splitPane.getItems().contains(dataPane)) { + splitPane.getItems().remove(dataPane); + } + statisticList.clear(); + histogramChart.getData().clear(); + adjustSplitPane(); + + } + + } catch (Exception e) { + logger.error(e.toString()); + } + + } + + public void loadData(Map imageData) { + if (imageData != null) { + this.imageData = imageData; + showData(); + } else { + loadData(); + } + } + + protected void loadData() { + imageData = null; + if (imageView.getImage() == null || isSettingValues + || dataCheck == null || !dataCheck.isSelected() + || dataPane == null) { + return; + } + task = new Task() { + @Override + protected Void call() throws Exception { + try { + imageData = ImageStatistic.analyze(SwingFXUtils.fromFXImage(imageView.getImage(), null)); + if (task.isCancelled() || imageData == null) { + return null; + } + Platform.runLater(new Runnable() { + @Override + public void run() { + showData(); + } + }); + } catch (Exception e) { + logger.debug(e.toString()); + } + return null; + } + }; + openHandlingStage(task, Modality.WINDOW_MODAL); + Thread thread = new Thread(task); + thread.setDaemon(true); + thread.start(); + } + + public void showData(Map imageData) { + this.imageData = imageData; + showData(); + } + + protected void showData() { + if (imageData == null || isSettingValues + || histogramChart == null) { + return; + } + statisticList.clear(); + clearHistogram(); + List statistic = (List) imageData.get("statistic"); + statisticList.addAll(statistic); + greyHistCheck.fire(); + adjustSplitPane(); + } + + protected void showHistogram(final String colorName) { + if (imageData == null || isSettingValues || colorName == null + || histogramChart == null || histogramChart.getData() == null) { + return; + } + for (Object s : histogramChart.getData()) { + XYChart.Series xy = (XYChart.Series) s; + if (colorName.equals(xy.getName())) { + return; + } + } + + int[] histogram; + final String colorValue; + if (AppVaribles.getMessage("Red").equals(colorName)) { + histogram = (int[]) imageData.get("redHistogram"); + colorValue = "Red"; + } else if (AppVaribles.getMessage("Green").equals(colorName)) { + histogram = (int[]) imageData.get("greenHistogram"); + colorValue = "Green"; + } else if (AppVaribles.getMessage("Blue").equals(colorName)) { + histogram = (int[]) imageData.get("blueHistogram"); + colorValue = "Blue"; + } else if (AppVaribles.getMessage("Alpha").equals(colorName)) { + histogram = (int[]) imageData.get("alphaHistogram"); + colorValue = "SkyBlue"; + } else if (AppVaribles.getMessage("Hue").equals(colorName)) { + histogram = (int[]) imageData.get("hueHistogram"); + colorValue = "Pink"; + } else if (AppVaribles.getMessage("Brightness").equals(colorName)) { + histogram = (int[]) imageData.get("brightnessHistogram"); + colorValue = "Wheat"; + } else if (AppVaribles.getMessage("Saturation").equals(colorName)) { + histogram = (int[]) imageData.get("saturationHistogram"); + colorValue = "DarkRed"; + } else { + histogram = (int[]) imageData.get("greyHistogram"); + colorValue = "Gray"; + } + + XYChart.Series series = new XYChart.Series(); + for (int i = 0; i < histogram.length; i++) { + series.getData().add(new XYChart.Data(i + "", histogram[i])); + } + series.setName(colorName); + + histogramChart.getData().addAll(series); + int index = histogramChart.getData().size() - 1; + String colorString = FxmlColor.rgb2Hex(colorTable.get(colorName)); + for (Node n : histogramChart.lookupAll(".default-color" + index + ".chart-bar")) { + n.setStyle("-fx-bar-fill: " + colorString); + } + updateLegend(); + + } + + // https://stackoverflow.com/questions/12197877/javafx-linechart-legend-style + private void updateLegend() { + if (histogramChart == null) { + return; + } + for (Node n : histogramChart.getChildrenUnmodifiable()) { + if (n instanceof Legend) { + for (Legend.LegendItem legendItem : ((Legend) n).getItems()) { + String colorString = FxmlColor.rgb2Hex(colorTable.get(legendItem.getText())); + legendItem.getSymbol().setStyle("-fx-background-color: " + colorString); + } + } + } + } + + protected void hideHistogram(String color) { + if (imageData == null || isSettingValues || color == null + || histogramChart == null || histogramChart.getData() == null) { + return; + } + for (Object s : histogramChart.getData()) { + XYChart.Series xy = (XYChart.Series) s; + if (color.equals(xy.getName())) { + histogramChart.getData().remove(s); + updateLegend(); + return; + } + } + } + + @FXML + public void clearHistogram() { + if (histogramChart != null) { + isSettingValues = true; + greyHistCheck.setSelected(false); + redHistCheck.setSelected(false); + greenHistCheck.setSelected(false); + blueHistCheck.setSelected(false); + alphaHistCheck.setSelected(false); + hueHistCheck.setSelected(false); + saturationHistCheck.setSelected(false); + brightnessHistCheck.setSelected(false); + isSettingValues = false; + histogramChart.getData().clear(); + } + } + + @FXML + protected void colorChecked(ActionEvent event) { + CheckBox checked = (CheckBox) event.getSource(); + if (checked.isSelected()) { + showHistogram(checked.getText()); + } else { + hideHistogram(checked.getText()); + } + } + + protected void adjustSplitPane() { + try { + int size = splitPane.getItems().size(); + float p = 1.0f / size; + if (size == 1) { + splitPane.setDividerPositions(1); + } else { + for (int i = 0; i < size - 1; i++) { + splitPane.getDividers().get(i).setPosition(p); + } + } + splitPane.layout(); + fitSize(); + } catch (Exception e) { + logger.error(e.toString()); + } + } + @Override public void sourceFileChanged(final File file) { if (file.isDirectory()) { @@ -166,15 +654,30 @@ public void sourceFileChanged(final File file) { @Override protected void afterInfoLoaded() { - if (infoBar != null) { - infoBar.setDisable(imageInformation == null); - } if (infoButton != null) { infoButton.setDisable(imageInformation == null); } if (metaButton != null) { metaButton.setDisable(imageInformation == null); } + if (statisticButton != null) { + statisticButton.setDisable(image == null); + } + if (deleteButton != null) { + deleteButton.setDisable(sourceFile == null); + } + if (renameButton != null) { + renameButton.setDisable(sourceFile == null); + } + if (deleteConfirmCheck != null) { + deleteConfirmCheck.setDisable(sourceFile == null); + } + if (navBox != null) { + navBox.setDisable(sourceFile == null); + } + if (manufactureButton != null) { + manufactureButton.setDisable(imageInformation == null && image == null); + } } @@ -185,7 +688,6 @@ public void afterImageLoaded() { if (image == null) { return; } - imageView.setPreserveRatio(true); imageView.setImage(image); @@ -218,16 +720,21 @@ public void afterImageLoaded() { } } - if (sourceFile != null && navBar != null) { - navBar.setDisable(false); + if (sourceFile != null && navBox != null) { checkImageNevigator(); } - if (cropButton != null) { - selectAllAction(); - Tooltip tips = new Tooltip(getMessage("CropLabel")); - tips.setFont(new Font(16)); - FxmlTools.quickTooltip(cropButton, tips); + if (cropCheck != null) { + checkSelect(); + } else { + cropLeftX = 0; + cropLeftY = 0; + cropRightX = (int) image.getWidth() - 1; + cropRightY = (int) image.getHeight() - 1; + } + + if (dataPane != null) { + loadData(imageData); } } catch (Exception e) { @@ -309,16 +816,17 @@ public void handle(ActionEvent event) { = (ImageViewerController) reloadStage(CommonValues.ImageViewerFxml, AppVaribles.getMessage("ImageViewer")); controller.loadImage(sourceFile, image, imageInformation); } else if (result.get() == buttonSave) { - saveAs(); + saveAction(); } } @Override - protected void handleMultipleImages() { + protected void handleMultipleFramesImage() { Alert alert = new Alert(Alert.AlertType.CONFIRMATION); alert.setTitle(getMyStage().getTitle()); alert.setContentText(getMessage("MultipleFramesImagesInfo")); + alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); ButtonType buttonSure = new ButtonType(AppVaribles.getMessage("Sure")); ButtonType buttonCancel = new ButtonType(AppVaribles.getMessage("Cancel")); @@ -340,14 +848,32 @@ protected void handleMultipleImages() { controller.openFile(sourceFile); } } + + if (sourceFile != null && navBox != null) { + navBox.setDisable(false); + checkImageNevigator(); + } } @FXML - public void popImageInformation() { + @Override + public void infoAction() { + if (imageInformation == null) { + return; + } showImageInformation(imageInformation); } @FXML + public void statisticAction() { + if (image == null) { + return; + } + showImageStatistic(image); + } + + @FXML + @Override public void nextAction() { if (nextFile != null) { loadImage(nextFile.getAbsoluteFile(), false); @@ -355,6 +881,7 @@ public void nextAction() { } @FXML + @Override public void previousAction() { if (previousFile != null) { loadImage(previousFile.getAbsoluteFile(), false); @@ -362,11 +889,23 @@ public void previousAction() { } @FXML - public void browseAction() { + public void browseImagesAction() { + try { + final ImagesBrowserController controller = FxmlStage.openImagesBrowser(getClass(), null); + if (controller != null && sourceFile != null) { + controller.loadImages(sourceFile.getParentFile(), 9); + } + } catch (Exception e) { + logger.error(e.toString()); + } + } + + @FXML + public void viewImageAction() { try { - final ImagesViewerController controller = OpenFile.openImagesViewer(getClass(), null); - if (controller != null) { - controller.loadImages(sourceFile.getParentFile(), 16); + final ImageViewerController controller = FxmlStage.openImageViewer(getClass(), null); + if (controller != null && sourceFile != null) { + controller.loadImage(sourceFile, false); } } catch (Exception e) { logger.error(e.toString()); @@ -379,6 +918,7 @@ public void popMetaData() { } @FXML + @Override public void zoomIn() { double currentWidth = imageView.getFitWidth(); if (currentWidth == -1) { @@ -393,6 +933,7 @@ public void zoomIn() { } @FXML + @Override public void zoomOut() { double currentWidth = imageView.getFitWidth(); if (currentWidth == -1) { @@ -413,6 +954,7 @@ public void zoomOut() { } @FXML + @Override public void imageSize() { imageView.setFitWidth(imageView.getImage().getWidth()); imageView.setFitHeight(imageView.getImage().getHeight()); @@ -420,6 +962,7 @@ public void imageSize() { } @FXML + @Override public void paneSize() { imageView.setFitWidth(scrollPane.getWidth() - 1); imageView.setFitHeight(scrollPane.getHeight() - 5); @@ -482,24 +1025,28 @@ public void straighten() { } @FXML + @Override public void selectAllAction() { if (image == null) { return; - }; + } cropLeftX = 0; cropLeftY = 0; cropRightX = (int) image.getWidth() - 1; cropRightY = (int) image.getHeight() - 1; imageView.setImage(image); - bottomLabel.setText(AppVaribles.getMessage("SelectedSize") + ": " + (cropRightX - cropLeftX + 1) + "x" + (cropRightY - cropLeftY + 1)); + bottomLabel.setText(AppVaribles.getMessage("SelectedSize") + ": " + + (cropRightX - cropLeftX + 1) + "x" + (cropRightY - cropLeftY + 1)); } @FXML public void clickImage(MouseEvent event) { - if (cropButton == null || image == null) { + if (image == null + || (cropCheck != null && !cropCheck.isSelected())) { imageView.setCursor(Cursor.OPEN_HAND); return; } + imageView.setCursor(Cursor.HAND); int x = (int) Math.round(event.getX() * image.getWidth() / imageView.getBoundsInLocal().getWidth()); @@ -516,10 +1063,8 @@ public void clickImage(MouseEvent event) { if (cropLeftX < cropRightX && cropLeftY < cropRightY) { indicateSelection(); - cropButton.setDisable(false); - bottomLabel.setText(getMessage("SelectedSize") + ": " + (cropRightX - cropLeftX + 1) + "x" + (cropRightY - cropLeftY + 1)); - } else { - cropButton.setDisable(true); + bottomLabel.setText(getMessage("SelectedSize") + ": " + + (cropRightX - cropLeftX + 1) + "x" + (cropRightY - cropLeftY + 1)); } } @@ -543,7 +1088,7 @@ protected Void call() throws Exception { @Override public void run() { imageView.setImage(newImage); -// popInformation(AppVaribles.getMessage("CropComments")); +// infoAction(AppVaribles.getMessage("CropComments")); } }); } catch (Exception e) { @@ -558,18 +1103,31 @@ public void run() { thread.start(); } + protected boolean isWholeImage(Image currentImage) { + return cropLeftX == 0 + && cropLeftY == 0 + && cropRightX == (int) currentImage.getWidth() - 1 + && cropRightY == (int) currentImage.getHeight() - 1; + } + @FXML - public void copySelectionAction() { - copySelectionAction(imageView.getImage()); + @Override + public void copyAction() { + if (imageView == null) { + return; + } + copyAction(imageView.getImage()); } - public void copySelectionAction(Image currentImage) { + public void copyAction(Image currentImage) { + if (currentImage == null || copyButton == null) { + return; + } Image cropImage; - if (cropLeftX == 0 && cropLeftY == 0 - && cropRightX == (int) currentImage.getWidth() && cropRightY == (int) currentImage.getHeight()) { + if (isWholeImage(currentImage)) { cropImage = currentImage; } else { - cropImage = FxmlImageTools.cropImage(currentImage, cropLeftX, cropLeftY, cropRightX, cropRightY); + cropImage = ImageTools.cropImage(currentImage, cropLeftX, cropLeftY, cropRightX, cropRightY); } ClipboardContent cc = new ClipboardContent(); cc.putImage(cropImage); @@ -578,80 +1136,17 @@ public void copySelectionAction(Image currentImage) { } @FXML - public void cropAction() { - try { - final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(targetPathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); - fileChooser.getExtensionFilters().addAll(CommonValues.ImageExtensionFilter); - final File file = fileChooser.showSaveDialog(getMyStage()); - if (file == null) { - return; - } - AppVaribles.setUserConfigValue(targetPathKey, file.getParent()); - - task = new Task() { - private boolean ok; - - @Override - protected Void call() throws Exception { - try { - Image cropImage = FxmlImageTools.cropImage(image, - cropLeftX, cropLeftY, cropRightX, cropRightY); - String format = FileTools.getFileSuffix(file.getName()); - BufferedImage bufferedImage = FxmlImageTools.getBufferedImage(cropImage); - if (task.isCancelled()) { - return null; - } - ok = ImageFileWriters.writeImageFile(bufferedImage, format, file.getAbsolutePath()); - if (task.isCancelled()) { - return null; - } - Platform.runLater(new Runnable() { - @Override - public void run() { - if (ok) { - Alert alert = new Alert(Alert.AlertType.CONFIRMATION); - alert.setTitle(getMyStage().getTitle()); - alert.setContentText(AppVaribles.getMessage("Successful")); - ButtonType buttonOpen = new ButtonType(AppVaribles.getMessage("Open")); - ButtonType buttonCancel = new ButtonType(AppVaribles.getMessage("Close")); - alert.getButtonTypes().setAll(buttonOpen, buttonCancel); - - Optional result = alert.showAndWait(); - if (result.get() == buttonOpen) { - openImageViewer(file.getAbsolutePath()); - } - } else { - popInformation(AppVaribles.getMessage("Failed")); - } - } - }); - return null; - } catch (Exception e) { - logger.debug(e.toString()); - } - return null; - } - }; - openHandlingStage(task, Modality.WINDOW_MODAL); - Thread thread = new Thread(task); - thread.setDaemon(true); - thread.start(); - - } catch (Exception e) { - logger.error(e.toString()); + @Override + public void saveAction() { + if (image == null) { + return; } - - } - - @FXML - public void saveAs() { try { - if (imageInformation.isIsSampled()) { + if (imageInformation != null && imageInformation.isIsSampled()) { Alert alert = new Alert(Alert.AlertType.CONFIRMATION); alert.setTitle(getMyStage().getTitle()); alert.setContentText(getMessage("SureSaveSampled")); + alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); ButtonType buttonSure = new ButtonType(AppVaribles.getMessage("Sure")); ButtonType buttonCancel = new ButtonType(AppVaribles.getMessage("Cancel")); @@ -664,35 +1159,58 @@ public void saveAs() { } final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(targetPathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); - fileChooser.getExtensionFilters().addAll(fileExtensionFilter); + File path = AppVaribles.getUserConfigPath(targetPathKey); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } + fileChooser.getExtensionFilters().addAll(CommonValues.ImageExtensionFilter); final File file = fileChooser.showSaveDialog(getMyStage()); if (file == null) { return; } AppVaribles.setUserConfigValue(targetPathKey, file.getParent()); - Task saveTask = new Task() { + task = new Task() { + private boolean ok; + @Override protected Void call() throws Exception { + Image savedImage = image; + if (cropCheck != null && cropCheck.isSelected()) { + if (!isWholeImage(image)) { + savedImage = ImageTools.cropImage(image, + cropLeftX, cropLeftY, cropRightX, cropRightY); + } + } String format = FileTools.getFileSuffix(file.getName()); - final BufferedImage bufferedImage = FxmlImageTools.getBufferedImage(image); + final BufferedImage bufferedImage = ImageTools.getBufferedImage(savedImage); + if (task.isCancelled()) { + return null; + } + ok = bufferedImage != null + && ImageFileWriters.writeImageFile(bufferedImage, format, file.getAbsolutePath()); if (task.isCancelled()) { return null; } - ImageFileWriters.writeImageFile(bufferedImage, format, file.getAbsolutePath()); Platform.runLater(new Runnable() { @Override public void run() { - popInformation(AppVaribles.getMessage("Successful")); + if (ok) { + if (openSaveCheck != null && openSaveCheck.isSelected()) { + openImageViewer(file.getAbsolutePath()); + } else { + popInformation(AppVaribles.getMessage("Successful")); + } + } else { + popInformation(AppVaribles.getMessage("Failed")); + } } }); return null; } }; - openHandlingStage(saveTask, Modality.WINDOW_MODAL); - Thread thread = new Thread(saveTask); + openHandlingStage(task, Modality.WINDOW_MODAL); + Thread thread = new Thread(task); thread.setDaemon(true); thread.start(); @@ -702,65 +1220,143 @@ public void run() { } + @FXML @Override - protected void keyEventsHandler(KeyEvent event) { - super.keyEventsHandler(event); - String key = event.getText(); - if (key == null || key.isEmpty()) { - return; - } - if (event.isControlDown()) { - switch (key) { - case "c": - copySelectionAction(); - break; + public void deleteAction() { + if (deleteFile(sourceFile)) { + sourceFile = null; + image = null; + imageView.setImage(null); + if (nextFile != null) { + nextAction(); + } else if (previousFile != null) { + previousAction(); + } else { + navBox.setDisable(true); } } } - public void setQuickTips() { - if (iButton != null) { - FxmlTools.quickTooltip(iButton, new Tooltip(AppVaribles.getMessage("ImageInformation"))); - FxmlTools.quickTooltip(mButton, new Tooltip(AppVaribles.getMessage("ImageMetaData"))); + public boolean deleteFile(File sfile) { + if (sfile == null) { + return false; } - if (pButton != null) { - FxmlTools.quickTooltip(pButton, new Tooltip(AppVaribles.getMessage("PaneSize"))); - FxmlTools.quickTooltip(gButton, new Tooltip(AppVaribles.getMessage("ImageSize"))); - FxmlTools.quickTooltip(inButton, new Tooltip(AppVaribles.getMessage("ZoomIn"))); - FxmlTools.quickTooltip(outButton, new Tooltip(AppVaribles.getMessage("ZoomOut"))); - FxmlTools.quickTooltip(lButton, new Tooltip(AppVaribles.getMessage("RotateLeft"))); - FxmlTools.quickTooltip(rButton, new Tooltip(AppVaribles.getMessage("RotateRight"))); - FxmlTools.quickTooltip(tButton, new Tooltip(AppVaribles.getMessage("TurnOver"))); - FxmlTools.quickTooltip(sButton, new Tooltip(AppVaribles.getMessage("Straighten"))); + if (deleteConfirmCheck != null && deleteConfirmCheck.isSelected()) { + Alert alert = new Alert(Alert.AlertType.CONFIRMATION); + alert.setTitle(getMyStage().getTitle()); + alert.setContentText(AppVaribles.getMessage("SureDelete")); + alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); + ButtonType buttonSure = new ButtonType(AppVaribles.getMessage("Sure")); + ButtonType buttonCancel = new ButtonType(AppVaribles.getMessage("Cancel")); + alert.getButtonTypes().setAll(buttonSure, buttonCancel); + Optional result = alert.showAndWait(); + if (result.get() == buttonCancel) { + return false; + } } - if (mrButton != null) { - FxmlTools.quickTooltip(mrButton, new Tooltip(AppVaribles.getMessage("MoveRight"))); - FxmlTools.quickTooltip(mlButton, new Tooltip(AppVaribles.getMessage("MoveLeft"))); - FxmlTools.quickTooltip(upButton, new Tooltip(AppVaribles.getMessage("MoveUp"))); - FxmlTools.quickTooltip(downButton, new Tooltip(AppVaribles.getMessage("MoveDown"))); + if (sfile.delete()) { + popInformation(AppVaribles.getMessage("Successful")); + return true; + } else { + popError(AppVaribles.getMessage("Failed")); + return false; } } - public void setTips() { - if (iButton != null) { - iButton.setTooltip(new Tooltip(AppVaribles.getMessage("ImageInformation"))); - mButton.setTooltip(new Tooltip(AppVaribles.getMessage("ImageMetaData"))); + @FXML + public void renameAction() { + try { + File file = renameFile(sourceFile); + if (file == null) { + return; + } + sourceFile = file; + if (imageInformation != null) { + ImageFileInformation finfo = imageInformation.getImageFileInformation(); + if (finfo != null) { + finfo.setFile(file); + finfo.setFileName(file.getAbsolutePath()); + } + imageInformation.setFilename(file.getAbsolutePath()); + } + if (imageInformation != null && imageInformation.isIsSampled()) { + if (imageInformation.getIndex() > 0) { + getMyStage().setTitle(getBaseTitle() + " " + sourceFile.getAbsolutePath() + + " - " + getMessage("Image") + " " + imageInformation.getIndex() + + " " + getMessage("Sampled")); + } else { + getMyStage().setTitle(getBaseTitle() + " " + sourceFile.getAbsolutePath() + + " " + getMessage("Sampled")); + } + + } else { + if (imageInformation != null && imageInformation.getIndex() > 0) { + getMyStage().setTitle(getBaseTitle() + " " + sourceFile.getAbsolutePath() + + " - " + getMessage("Image") + " " + imageInformation.getIndex()); + } else { + getMyStage().setTitle(getBaseTitle() + " " + sourceFile.getAbsolutePath()); + } + bottomLabel.setText(""); + } + checkImageNevigator(); + + } catch (Exception e) { + logger.error(e.toString()); } - if (pButton != null) { - pButton.setTooltip(new Tooltip(AppVaribles.getMessage("PaneSize"))); - gButton.setTooltip(new Tooltip(AppVaribles.getMessage("ImageSize"))); - inButton.setTooltip(new Tooltip(AppVaribles.getMessage("ZoomIn"))); - outButton.setTooltip(new Tooltip(AppVaribles.getMessage("ZoomOut"))); - lButton.setTooltip(new Tooltip(AppVaribles.getMessage("RotateRight"))); - rButton.setTooltip(new Tooltip(AppVaribles.getMessage("RotateRight"))); - tButton.setTooltip(new Tooltip(AppVaribles.getMessage("TurnOver"))); - sButton.setTooltip(new Tooltip(AppVaribles.getMessage("Straighten"))); + + } + + public File renameFile(File sfile) { + if (sfile == null) { + return null; } - if (mrButton != null) { - mrButton.setTooltip(new Tooltip(AppVaribles.getMessage("MoveRight"))); - mlButton.setTooltip(new Tooltip(AppVaribles.getMessage("MoveLeft"))); - upButton.setTooltip(new Tooltip(AppVaribles.getMessage("MoveUp"))); - downButton.setTooltip(new Tooltip(AppVaribles.getMessage("MoveDown"))); + try { + final FileChooser fileChooser = new FileChooser(); + File path = AppVaribles.getUserConfigPath(targetPathKey); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } + fileChooser.getExtensionFilters().addAll(CommonValues.ImageExtensionFilter); + final File file = fileChooser.showSaveDialog(getMyStage()); + if (file == null) { + return null; + } + AppVaribles.setUserConfigValue(targetPathKey, file.getParent()); + + if (file.exists()) { + if (!file.delete()) { + popError(AppVaribles.getMessage("Failed")); + } + } + + if (sfile.renameTo(file)) { + popInformation(AppVaribles.getMessage("Successful")); + return file; + } else { + popError(AppVaribles.getMessage("Failed")); + return null; + } + + } catch (Exception e) { + logger.error(e.toString()); + return null; + } + + } + + @FXML + protected void manufactureAction() { + if (image == null) { + return; + } + try { + final ImageManufactureController controller + = (ImageManufactureController) FxmlStage.openStage(getClass(), null, + CommonValues.ImageManufactureFileFxml, AppVaribles.getMessage("ImageManufacture")); + controller.loadImage(sourceFile, image, imageInformation); + controller.loadData(imageData); + } catch (Exception e) { + logger.error(e.toString()); } } @@ -843,68 +1439,36 @@ public void setMouseY(double mouseY) { this.mouseY = mouseY; } - public Button getiButton() { - return iButton; - } - - public void setiButton(Button iButton) { - this.iButton = iButton; - } - - public Button getmButton() { - return mButton; - } - - public void setmButton(Button mButton) { - this.mButton = mButton; - } - - public Button getgButton() { - return gButton; - } - - public void setgButton(Button gButton) { - this.gButton = gButton; - } - - public Button getpButton() { - return pButton; - } - - public void setpButton(Button pButton) { - this.pButton = pButton; - } - - public Button getInButton() { - return inButton; + public Button getImageSizeButton() { + return imageSizeButton; } - public void setInButton(Button inButton) { - this.inButton = inButton; + public void setImageSizeButton(Button imageSizeButton) { + this.imageSizeButton = imageSizeButton; } - public Button getOutButton() { - return outButton; + public Button getPaneSizeButton() { + return paneSizeButton; } - public void setOutButton(Button outButton) { - this.outButton = outButton; + public void setPaneSizeButton(Button paneSizeButton) { + this.paneSizeButton = paneSizeButton; } - public Button getlButton() { - return lButton; + public Button getZoomInButton() { + return zoomInButton; } - public void setlButton(Button lButton) { - this.lButton = lButton; + public void setZoomInButton(Button zoomInButton) { + this.zoomInButton = zoomInButton; } - public Button getrButton() { - return rButton; + public Button getZoomOutButton() { + return zoomOutButton; } - public void setrButton(Button rButton) { - this.rButton = rButton; + public void setZoomOutButton(Button zoomOutButton) { + this.zoomOutButton = zoomOutButton; } public int getxZoomStep() { diff --git a/MyBox/src/main/java/mara/mybox/controller/ImageViewerIController.java b/MyBox/src/main/java/mara/mybox/controller/ImageViewerIController.java index f4276480f..e3db71643 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImageViewerIController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImageViewerIController.java @@ -1,13 +1,5 @@ package mara.mybox.controller; -import javafx.fxml.FXML; -import javafx.scene.input.MouseEvent; -import javafx.scene.layout.HBox; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.AppVaribles; -import mara.mybox.tools.DateTools; -import mara.mybox.tools.FileTools; - /** * @Author Mara * @CreateDate 2018-6-28 @@ -16,58 +8,4 @@ */ public class ImageViewerIController extends ImageViewerController { - protected boolean isRefer; - - @FXML - private HBox buttonsBox; - - @Override - protected void initializeNext2() { - try { - setTips(); - } catch (Exception e) { - logger.error(e.toString()); - } - } - - @FXML - @Override - public void clickImage(MouseEvent event) { - if (!isRefer && event.getClickCount() > 1) { - openImageManufacture(sourceFile.getAbsolutePath()); -// try { -// FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(CommonValues.ImageManufactureFileFxml), AppVaribles.CurrentBundle); -// Pane pane = fxmlLoader.load(); -// ImageManufactureController controller = fxmlLoader.getController(); -// controller.loadImage(sourceFile.getAbsolutePath()); -// -// controller.setMyStage(getMyStage()); -// myStage.setScene(new Scene(pane)); -// } catch (Exception e) { -// logger.error(e.toString()); -// } - } - } - - @FXML - void imageEntered(MouseEvent event) { - String str = AppVaribles.getMessage("Format") + ":" + imageInformation.getImageFormat() + " " - + AppVaribles.getMessage("Pixels") + ":" + imageInformation.getWidth() + "x" + imageInformation.getHeight() + " " - + AppVaribles.getMessage("Size") + ":" + FileTools.showFileSize(sourceFile.length()) + " " - + AppVaribles.getMessage("ModifyTime") + ":" + DateTools.datetimeToString(sourceFile.lastModified()); - parentController.bottomLabel.setText(str); - } - - public void removeButtons() { - thisPane.getChildren().remove(buttonsBox); - } - - public boolean isIsRefer() { - return isRefer; - } - - public void setIsRefer(boolean isRefer) { - this.isRefer = isRefer; - } - } diff --git a/MyBox/src/main/java/mara/mybox/controller/ImagesBlendController.java b/MyBox/src/main/java/mara/mybox/controller/ImagesBlendController.java index 0972a7e97..7e3a69758 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImagesBlendController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImagesBlendController.java @@ -30,17 +30,16 @@ import javafx.stage.FileChooser; import javafx.stage.Modality; import javax.imageio.ImageIO; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.fxml.FxmlImageTools; -import mara.mybox.image.ImageBlendTools.ImagesBlendMode; -import mara.mybox.image.ImageBlendTools.ImagesRelativeLocation; -import mara.mybox.imagefile.ImageFileReaders; -import mara.mybox.imagefile.ImageFileWriters; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.CommonValues; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.fxml.image.ImageTools; +import mara.mybox.image.ImageBlend.ImagesBlendMode; +import mara.mybox.image.ImageBlend.ImagesRelativeLocation; +import mara.mybox.image.file.ImageFileReaders; +import mara.mybox.image.file.ImageFileWriters; +import mara.mybox.value.AppVaribles; import mara.mybox.tools.FileTools; import static mara.mybox.fxml.FxmlTools.badStyle; -import mara.mybox.objects.ImageInformation; +import mara.mybox.data.ImageInformation; /** * @Author Mara @@ -78,11 +77,9 @@ public class ImagesBlendController extends ImageViewerController { @FXML private ComboBox targetTypeBox, blendModeBox, opacityBox; @FXML - private Label foreTitle, foreLabel, backTitle, backLabel; + private Label foreTitle, foreLabel, backTitle, backLabel, pointLabel; @FXML - private Label pointLabel; - @FXML - private Button saveButton, imageSizeButton, paneSizeButton, zoomInButton, zoomOutButton, newWindowButton; + private Button newWindowButton; @FXML private TextField pointX, pointY; @FXML @@ -350,8 +347,10 @@ private void initTargetSection() { private void selectForegroundImage(ActionEvent event) { try { final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(sourcePathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(sourcePathKey); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } fileChooser.getExtensionFilters().addAll(fileExtensionFilter); final File file = fileChooser.showOpenDialog(getMyStage()); if (file == null) { @@ -414,7 +413,7 @@ public void run() { @FXML private void openForegroundImage(ActionEvent event) { if (foreFile != null) { - openImageManufacture(foreFile.getAbsolutePath()); + openImageViewer(foreFile.getAbsolutePath()); } } @@ -434,8 +433,10 @@ private void setForegroundImageSize(ActionEvent event) { private void selectBackgroundImage(ActionEvent event) { try { final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(sourcePathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(sourcePathKey); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } fileChooser.getExtensionFilters().addAll(fileExtensionFilter); final File file = fileChooser.showOpenDialog(getMyStage()); if (file == null) { @@ -507,7 +508,7 @@ private void afterImagesOpened() { @FXML private void openBackgroundImage(ActionEvent event) { if (backFile != null) { - openImageManufacture(backFile.getAbsolutePath()); + openImageViewer(backFile.getAbsolutePath()); } } @@ -524,14 +525,17 @@ private void setBackgroundImageSize(ActionEvent event) { } @FXML - private void saveAction(ActionEvent event) { + @Override + public void saveAction() { if (image == null) { return; } try { final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(targetPathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(targetPathKey); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } fileChooser.getExtensionFilters().addAll(fileExtensionFilter); final File file = fileChooser.showSaveDialog(getMyStage()); if (file == null) { @@ -546,7 +550,7 @@ protected Void call() throws Exception { try { String filename = targetFile.getAbsolutePath(); String format = FileTools.getFileSuffix(filename); - final BufferedImage bufferedImage = FxmlImageTools.getBufferedImage(image); + final BufferedImage bufferedImage = ImageTools.getBufferedImage(image); if (task.isCancelled()) { return null; } @@ -635,7 +639,7 @@ private void blendImages() { bottomLabel.setText(AppVaribles.getMessage("Loading...")); - image = FxmlImageTools.blendImages(foreImage, backImage, + image = ImageTools.blendImages(foreImage, backImage, location, x, y, intersectOnlyCheck.isSelected(), blendMode, opacity); if (image == null) { bottomLabel.setText(""); diff --git a/MyBox/src/main/java/mara/mybox/controller/ImagesViewerController.java b/MyBox/src/main/java/mara/mybox/controller/ImagesBrowserController.java similarity index 61% rename from MyBox/src/main/java/mara/mybox/controller/ImagesViewerController.java rename to MyBox/src/main/java/mara/mybox/controller/ImagesBrowserController.java index 4f3ca933a..f59d76b68 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImagesViewerController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImagesBrowserController.java @@ -10,28 +10,33 @@ import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.event.ActionEvent; +import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; +import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.control.Button; -import javafx.scene.control.CheckBox; import javafx.scene.control.ComboBox; import javafx.scene.control.RadioButton; import javafx.scene.control.ToolBar; import javafx.scene.control.Tooltip; +import javafx.scene.input.MouseEvent; import javafx.scene.layout.HBox; import javafx.scene.layout.Pane; import javafx.scene.layout.Priority; import javafx.scene.layout.VBox; import javafx.stage.FileChooser; import javafx.stage.Modality; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.CommonValues; +import mara.mybox.fxml.FxmlStage; +import mara.mybox.value.AppVaribles; +import mara.mybox.value.CommonValues; import mara.mybox.tools.FileTools; import mara.mybox.fxml.FxmlTools; import static mara.mybox.fxml.FxmlTools.badStyle; +import static mara.mybox.value.AppVaribles.getMessage; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.data.ImageInformation; +import mara.mybox.tools.DateTools; /** * @Author Mara @@ -39,29 +44,32 @@ * @Description * @License Apache License Version 2.0 */ -public class ImagesViewerController extends ImageViewerController { +public class ImagesBrowserController extends ImageViewerController { private final ObservableList imageFileList = FXCollections.observableArrayList(); private int rowsNum, colsNum, filesNumber; private List imagePaneList; private List imageControllerList; protected List nextFiles, previousFiles; + protected List selectedFiles; protected String ImageSortTypeKey = "ImageSortType"; - private boolean isSettingValues; + protected int maxShow = 100; @FXML protected VBox imagesPane; @FXML - protected Button selectButton; + protected Button selectButton, viewButton; @FXML - protected ToolBar setBar; + protected ToolBar setBar, fileOpBar; @FXML protected ComboBox colsnumBox, filesBox; @FXML - private CheckBox eachCheck; - @FXML private HBox opBox; + public ImagesBrowserController() { + TipsLabelKey = "ImageBrowserTips"; + } + @Override protected void initializeNext2() { try { @@ -112,21 +120,12 @@ public void changed(ObservableValue ov, String oldValue, String newValue) { } }); - eachCheck.selectedProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue observable, - Boolean oldValue, Boolean newValue) { - makeImagesPane(); - } - }); - FxmlTools.quickTooltip(selectButton, new Tooltip(AppVaribles.getMessage("ImagesMutipleTips"))); - setTips(); opBox.disableProperty().bind( Bindings.isEmpty(imageFileList) ); - navBar.disableProperty().bind( + navBox.disableProperty().bind( Bindings.isEmpty(imageFileList) ); setBar.disableProperty().bind( @@ -143,8 +142,10 @@ protected void selectImages(ActionEvent event) { try { final FileChooser fileChooser = new FileChooser(); - String defaultPath = AppVaribles.getUserConfigPath(LastPathKey, CommonValues.UserFilePath); - fileChooser.setInitialDirectory(new File(AppVaribles.getUserConfigValue(sourcePathKey, defaultPath))); + File defaultPath = AppVaribles.getUserConfigPath(sourcePathKey); + if (defaultPath.exists()) { + fileChooser.setInitialDirectory(defaultPath); + } fileChooser.getExtensionFilters().addAll(fileExtensionFilter); List files = fileChooser.showOpenMultipleDialog(getMyStage()); if (files == null || files.isEmpty()) { @@ -180,8 +181,17 @@ public void paneSize() { if (imageControllerList == null) { return; } - for (ImageViewerIController c : imageControllerList) { - c.paneSize(); + if (selectedFiles != null && !selectedFiles.isEmpty()) { + for (int index : selectedFiles) { + ImageViewerIController c = imageControllerList.get(index); + if (c != null) { + c.paneSize(); + } + } + } else { + for (ImageViewerIController c : imageControllerList) { + c.paneSize(); + } } } @@ -191,8 +201,17 @@ public void imageSize() { if (imageControllerList == null) { return; } - for (ImageViewerIController c : imageControllerList) { - c.imageSize(); + if (selectedFiles != null && !selectedFiles.isEmpty()) { + for (int index : selectedFiles) { + ImageViewerIController c = imageControllerList.get(index); + if (c != null) { + c.imageSize(); + } + } + } else { + for (ImageViewerIController c : imageControllerList) { + c.imageSize(); + } } } @@ -202,10 +221,18 @@ public void zoomIn() { if (imageControllerList == null) { return; } - for (ImageViewerIController c : imageControllerList) { - c.zoomIn(); + if (selectedFiles != null && !selectedFiles.isEmpty()) { + for (int index : selectedFiles) { + ImageViewerIController c = imageControllerList.get(index); + if (c != null) { + c.zoomIn(); + } + } + } else { + for (ImageViewerIController c : imageControllerList) { + c.zoomIn(); + } } - } @FXML @@ -214,10 +241,18 @@ public void zoomOut() { if (imageControllerList == null) { return; } - for (ImageViewerIController c : imageControllerList) { - c.zoomOut(); + if (selectedFiles != null && !selectedFiles.isEmpty()) { + for (int index : selectedFiles) { + ImageViewerIController c = imageControllerList.get(index); + if (c != null) { + c.zoomOut(); + } + } + } else { + for (ImageViewerIController c : imageControllerList) { + c.zoomOut(); + } } - } @FXML @@ -226,8 +261,17 @@ public void moveRight() { if (imageControllerList == null) { return; } - for (ImageViewerIController c : imageControllerList) { - c.moveRight(); + if (selectedFiles != null && !selectedFiles.isEmpty()) { + for (int index : selectedFiles) { + ImageViewerIController c = imageControllerList.get(index); + if (c != null) { + c.moveRight(); + } + } + } else { + for (ImageViewerIController c : imageControllerList) { + c.moveRight(); + } } } @@ -237,8 +281,17 @@ public void moveLeft() { if (imageControllerList == null) { return; } - for (ImageViewerIController c : imageControllerList) { - c.moveLeft(); + if (selectedFiles != null && !selectedFiles.isEmpty()) { + for (int index : selectedFiles) { + ImageViewerIController c = imageControllerList.get(index); + if (c != null) { + c.moveLeft(); + } + } + } else { + for (ImageViewerIController c : imageControllerList) { + c.moveLeft(); + } } } @@ -248,8 +301,17 @@ public void moveUp() { if (imageControllerList == null) { return; } - for (ImageViewerIController c : imageControllerList) { - c.moveUp(); + if (selectedFiles != null && !selectedFiles.isEmpty()) { + for (int index : selectedFiles) { + ImageViewerIController c = imageControllerList.get(index); + if (c != null) { + c.moveUp(); + } + } + } else { + for (ImageViewerIController c : imageControllerList) { + c.moveUp(); + } } } @@ -259,8 +321,17 @@ public void moveDown() { if (imageControllerList == null) { return; } - for (ImageViewerIController c : imageControllerList) { - c.moveDown(); + if (selectedFiles != null && !selectedFiles.isEmpty()) { + for (int index : selectedFiles) { + ImageViewerIController c = imageControllerList.get(index); + if (c != null) { + c.moveDown(); + } + } + } else { + for (ImageViewerIController c : imageControllerList) { + c.moveDown(); + } } } @@ -270,10 +341,18 @@ public void rotateLeft() { if (imageControllerList == null) { return; } - for (ImageViewerIController c : imageControllerList) { - c.rotateLeft(); + if (selectedFiles != null && !selectedFiles.isEmpty()) { + for (int index : selectedFiles) { + ImageViewerIController c = imageControllerList.get(index); + if (c != null) { + c.rotateLeft(); + } + } + } else { + for (ImageViewerIController c : imageControllerList) { + c.rotateLeft(); + } } - } @FXML @@ -282,10 +361,18 @@ public void rotateRight() { if (imageControllerList == null) { return; } - for (ImageViewerIController c : imageControllerList) { - c.rotateRight(); + if (selectedFiles != null && !selectedFiles.isEmpty()) { + for (int index : selectedFiles) { + ImageViewerIController c = imageControllerList.get(index); + if (c != null) { + c.rotateRight(); + } + } + } else { + for (ImageViewerIController c : imageControllerList) { + c.rotateRight(); + } } - } @FXML @@ -294,10 +381,18 @@ public void turnOver() { if (imageControllerList == null) { return; } - for (ImageViewerIController c : imageControllerList) { - c.turnOver(); + if (selectedFiles != null && !selectedFiles.isEmpty()) { + for (int index : selectedFiles) { + ImageViewerIController c = imageControllerList.get(index); + if (c != null) { + c.turnOver(); + } + } + } else { + for (ImageViewerIController c : imageControllerList) { + c.turnOver(); + } } - } @FXML @@ -306,10 +401,18 @@ public void straighten() { if (imageControllerList == null) { return; } - for (ImageViewerIController c : imageControllerList) { - c.straighten(); + if (selectedFiles != null && !selectedFiles.isEmpty()) { + for (int index : selectedFiles) { + ImageViewerIController c = imageControllerList.get(index); + if (c != null) { + c.straighten(); + } + } + } else { + for (ImageViewerIController c : imageControllerList) { + c.straighten(); + } } - } @FXML @@ -336,6 +439,88 @@ public void previousAction() { } } + @FXML + public void viewAction() { + try { + if (selectedFiles == null || selectedFiles.isEmpty()) { + fileOpBar.setDisable(true); + return; + } + int index = selectedFiles.get(0); + ImageViewerIController c = imageControllerList.get(index); + if (c != null) { + File file = c.getImageInformation().getImageFileInformation().getFile(); + FxmlStage.openImageViewer(getClass(), null, file); + } + } catch (Exception e) { + logger.error(e.toString()); + } + } + + @FXML + @Override + public void renameAction() { + try { + if (selectedFiles == null || selectedFiles.isEmpty()) { + fileOpBar.setDisable(true); + return; + } + int index = selectedFiles.get(0); + ImageViewerIController c = imageControllerList.get(index); + if (c != null) { + File file = c.getImageInformation().getImageFileInformation().getFile(); + if (renameFile(file) != null) { + imageFileList.remove(file); + makeNevigator(true); + makeImagesPane(); + } + } + } catch (Exception e) { + logger.error(e.toString()); + } + } + + @FXML + @Override + public void deleteAction() { + try { + if (selectedFiles == null || selectedFiles.isEmpty()) { + fileOpBar.setDisable(true); + return; + } + int index = selectedFiles.get(0); + ImageViewerIController c = imageControllerList.get(index); + if (c != null) { + File file = c.getImageInformation().getImageFileInformation().getFile(); + if (deleteFile(file)) { + imageFileList.remove(file); + makeNevigator(true); + makeImagesPane(); + } + } + } catch (Exception e) { + logger.error(e.toString()); + } + } + + @FXML + @Override + public void infoAction() { + try { + if (selectedFiles == null || selectedFiles.isEmpty()) { + fileOpBar.setDisable(true); + return; + } + int index = selectedFiles.get(0); + ImageViewerIController c = imageControllerList.get(index); + if (c != null) { + showImageInformation(c.getImageInformation()); + } + } catch (Exception e) { + logger.error(e.toString()); + } + } + private void makeImagesPane() { if (colsNum <= 0) { return; @@ -343,13 +528,14 @@ private void makeImagesPane() { imagesPane.getChildren().clear(); imagePaneList = new ArrayList(); imageControllerList = new ArrayList(); + selectedFiles = new ArrayList(); rowsNum = 0; + fileOpBar.setDisable(true); if (imageFileList == null || imageFileList.isEmpty()) { return; } try { int num = imageFileList.size(); - HBox line = new HBox(); for (int i = 0; i < num; i++) { if (i % colsNum == 0) { @@ -366,17 +552,14 @@ private void makeImagesPane() { FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(CommonValues.ImageViewerIFxml), AppVaribles.CurrentBundle); Pane imagePane = fxmlLoader.load(); ImageViewerIController imageController = fxmlLoader.getController(); - if (!eachCheck.isSelected()) { - imageController.removeButtons(); - } imageController.setMyStage(myStage); - imageController.setBaseTitle(AppVaribles.getMessage("ImageViewer")); imageController.loadImage(imageFileList.get(i), false); imageController.setParentController(this); - imagePane.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE); VBox.setVgrow(imagePane, Priority.ALWAYS); HBox.setHgrow(imagePane, Priority.ALWAYS); + imagePane.setPadding(new Insets(5, 5, 5, 5)); + line.getChildren().add(imagePane); imagePaneList.add(imagePane); imageControllerList.add(imageController); @@ -384,9 +567,48 @@ private void makeImagesPane() { double w = imagesPane.getWidth() / colsNum - 5; double h = imagesPane.getHeight() / rowsNum - 5; - for (Pane p : imagePaneList) { + for (int i = 0; i < imagePaneList.size(); i++) { + Pane p = imagePaneList.get(i); p.setPrefWidth(w); p.setPrefHeight(h); + final int index = i; + p.setOnMouseEntered(new EventHandler() { + @Override + public void handle(MouseEvent event) { + ImageInformation info = imageControllerList.get(index).getImageInformation(); + File file = info.getImageFileInformation().getFile(); + String str = info.getFilename() + " " + + AppVaribles.getMessage("Format") + ":" + info.getImageFormat() + " " + + AppVaribles.getMessage("Pixels") + ":" + info.getWidth() + "x" + info.getHeight() + " " + + AppVaribles.getMessage("Size") + ":" + FileTools.showFileSize(file.length()) + " " + + AppVaribles.getMessage("ModifyTime") + ":" + DateTools.datetimeToString(file.lastModified()); + bottomLabel.setText(str); + } + }); + p.setOnMouseClicked(new EventHandler() { + @Override + public void handle(MouseEvent event) { + Pane pane = imagePaneList.get(index); + + Integer o = new Integer(index); + if (selectedFiles.contains(o)) { + selectedFiles.remove(o); + pane.setStyle(null); + } else { + selectedFiles.add(o); + pane.setStyle("-fx-background-color:dodgerblue;-fx-text-fill:white;"); + } + fileOpBar.setDisable(selectedFiles.isEmpty()); + viewButton.setDisable(selectedFiles.size() > 1); + infoButton.setDisable(selectedFiles.size() > 1); + renameButton.setDisable(selectedFiles.size() > 1); + + if (event.getClickCount() > 1) { + File file = imageControllerList.get(index).getImageInformation().getImageFileInformation().getFile(); + FxmlStage.openImageViewer(getClass(), null, file); + } + } + }); } paneSize(); @@ -434,6 +656,7 @@ private void makeNevigator(boolean reload) { if (reload) { int start = sortedFiles.indexOf(firstFile); + imageFileList.clear(); for (int k = start; k < sortedFiles.size(); k++) { imageFileList.add(sortedFiles.get(k)); @@ -455,7 +678,7 @@ private void makeNevigator(boolean reload) { for (int i = 0; i < sortedFiles.size(); i++) { if (sortedFiles.get(i).getAbsoluteFile().equals(firstFile.getAbsoluteFile())) { - if (i < sortedFiles.size() - imageFileList.size() - 1) { + if (i < sortedFiles.size() - imageFileList.size()) { nextFiles = new ArrayList(); for (int k = i + imageFileList.size(); k < sortedFiles.size(); k++) { nextFiles.add(sortedFiles.get(k)); @@ -506,6 +729,7 @@ private void makeNevigator(boolean reload) { public void loadImages(File path, int number) { try { imageFileList.clear(); + filesNumber = 0; if (path == null || !path.isDirectory() || !path.exists() || number <= 0) { return; } @@ -513,7 +737,7 @@ public void loadImages(File path, int number) { if (file.isFile() && FileTools.isSupportedImage(file)) { imageFileList.add(file); } - if (imageFileList.size() == number) { + if (imageFileList.size() == number || imageFileList.size() >= maxShow) { break; } } @@ -547,8 +771,9 @@ public void loadImages(List fileNames, int cols) { if (fileNames == null || cols <= 0) { return; } - for (String name : fileNames) { - File file = new File(name); + int len = Math.min(maxShow, fileNames.size()); + for (int i = 0; i < len; i++) { + File file = new File(fileNames.get(i)); if (file.isFile() && FileTools.isSupportedImage(file)) { imageFileList.add(file); } diff --git a/MyBox/src/main/java/mara/mybox/controller/ImagesCombineController.java b/MyBox/src/main/java/mara/mybox/controller/ImagesCombineController.java index ec4d55145..a278e89c1 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImagesCombineController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImagesCombineController.java @@ -28,19 +28,19 @@ import javafx.scene.paint.Color; import javafx.stage.FileChooser; import javafx.stage.Modality; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.image.ImageConvertTools; -import mara.mybox.imagefile.ImageFileWriters; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.ImageCombine; -import mara.mybox.objects.ImageCombine.ArrayType; -import mara.mybox.objects.ImageCombine.CombineSizeType; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.image.ImageConvert; +import mara.mybox.image.file.ImageFileWriters; +import mara.mybox.value.AppVaribles; +import mara.mybox.value.CommonValues; +import mara.mybox.data.ImageCombine; +import mara.mybox.data.ImageCombine.ArrayType; +import mara.mybox.data.ImageCombine.CombineSizeType; import mara.mybox.tools.FileTools; import static mara.mybox.fxml.FxmlTools.badStyle; -import mara.mybox.fxml.FxmlImageTools; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.ImageInformation; +import mara.mybox.fxml.image.ImageTools; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.data.ImageInformation; import mara.mybox.tools.ValueTools; /** @@ -487,9 +487,9 @@ private void combineImages() { } if (imageCombine.getArrayType() == ArrayType.SingleColumn) { - image = ImageConvertTools.combineSingleColumn(imageCombine, sourceImages, false, true); + image = ImageConvert.combineSingleColumn(imageCombine, sourceImages, false, true); } else if (imageCombine.getArrayType() == ArrayType.SingleRow) { - image = ImageConvertTools.combineSingleRow(imageCombine, sourceImages, false, true); + image = ImageConvert.combineSingleRow(imageCombine, sourceImages, false, true); } else if (imageCombine.getArrayType() == ArrayType.ColumnsNumber) { image = combineImagesColumns(sourceImages); } else { @@ -516,16 +516,16 @@ private Image combineImagesColumns(List images) { for (ImageInformation imageInfo : images) { rowImages.add(imageInfo); if (rowImages.size() == imageCombine.getColumnsValue()) { - Image rowImage = ImageConvertTools.combineSingleRow(imageCombine, rowImages, true, false); + Image rowImage = ImageConvert.combineSingleRow(imageCombine, rowImages, true, false); rows.add(new ImageInformation(rowImage)); rowImages = new ArrayList(); } } if (!rowImages.isEmpty()) { - Image rowImage = ImageConvertTools.combineSingleRow(imageCombine, rowImages, true, false); + Image rowImage = ImageConvert.combineSingleRow(imageCombine, rowImages, true, false); rows.add(new ImageInformation(rowImage)); } - Image newImage = ImageConvertTools.combineSingleColumn(imageCombine, rows, true, true); + Image newImage = ImageConvert.combineSingleColumn(imageCombine, rows, true, true); return newImage; } catch (Exception e) { logger.error(e.toString()); @@ -535,13 +535,15 @@ private Image combineImagesColumns(List images) { @FXML @Override - protected void saveAction() { + public void saveAction() { if (image == null) { return; } final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(targetPathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(targetPathKey); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } fileChooser.getExtensionFilters().addAll(fileExtensionFilter); final File file = fileChooser.showSaveDialog(getMyStage()); if (file == null) { @@ -558,7 +560,7 @@ protected Void call() throws Exception { try { final String filename = targetFile.getAbsolutePath(); String format = FileTools.getFileSuffix(filename); - final BufferedImage bufferedImage = FxmlImageTools.getBufferedImage(image); + final BufferedImage bufferedImage = ImageTools.getBufferedImage(image); ok = ImageFileWriters.writeImageFile(bufferedImage, format, filename); if (task.isCancelled()) { return null; @@ -569,7 +571,7 @@ public void run() { if (ok) { popInformation(AppVaribles.getMessage("Successful")); if (openCheck.isSelected()) { - openImageManufacture(filename); + openImageViewer(filename); } } else { popError(AppVaribles.getMessage("Failed")); diff --git a/MyBox/src/main/java/mara/mybox/controller/ImagesCombinePdfController.java b/MyBox/src/main/java/mara/mybox/controller/ImagesCombinePdfController.java index e60263d6c..a3e108dff 100644 --- a/MyBox/src/main/java/mara/mybox/controller/ImagesCombinePdfController.java +++ b/MyBox/src/main/java/mara/mybox/controller/ImagesCombinePdfController.java @@ -1,5 +1,6 @@ package mara.mybox.controller; +import mara.mybox.fxml.FxmlStage; import java.awt.image.BufferedImage; import java.io.File; import java.util.Arrays; @@ -26,14 +27,14 @@ import javafx.scene.text.Font; import javafx.stage.FileChooser; import javafx.stage.Modality; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.CommonValues; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.value.CommonValues; import mara.mybox.fxml.FxmlTools; import static mara.mybox.fxml.FxmlTools.badStyle; -import mara.mybox.imagefile.ImageFileReaders; -import mara.mybox.objects.ImageInformation; +import mara.mybox.image.file.ImageFileReaders; +import mara.mybox.data.ImageInformation; import mara.mybox.tools.PdfTools; import mara.mybox.tools.PdfTools.PdfImageFormat; import org.apache.pdfbox.pdmodel.PDDocument; @@ -54,7 +55,7 @@ public class ImagesCombinePdfController extends ImageSourcesController { private PdfImageFormat pdfFormat; @FXML - protected CheckBox pageNumberCheck; + protected CheckBox pageNumberCheck, ditherCheck; @FXML protected ComboBox MarginsBox, standardSizeBox, standardDpiBox, jpegBox, fontBox; @FXML @@ -168,16 +169,7 @@ public void changed(ObservableValue ov, }); checkFormat(); - jpegBox.getItems().addAll(Arrays.asList( - "100", - "75", - "90", - "50", - "60", - "80", - "30", - "10" - )); + jpegBox.getItems().addAll(Arrays.asList("100", "75", "90", "50", "60", "80", "30", "10")); jpegBox.valueProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue ov, @@ -195,6 +187,7 @@ public void changed(ObservableValue observable, String oldValu } }); checkThreshold(); + FxmlTools.setComments(ditherCheck, new Tooltip(getMessage("DitherComments"))); MarginsBox.getItems().addAll(Arrays.asList("20", "10", "15", "5", "25", "30")); MarginsBox.valueProperty().addListener(new ChangeListener() { @@ -440,7 +433,7 @@ private void checkThreshold() { return; } threshold = Integer.valueOf(thresholdInput.getText()); - if (threshold >= 0 && threshold <= 100) { + if (threshold >= 0 && threshold <= 255) { thresholdInput.setStyle(null); } else { threshold = -1; @@ -454,7 +447,7 @@ private void checkThreshold() { @FXML @Override - protected void saveAction() { + public void saveAction() { if (sourceImages == null || sourceImages.isEmpty()) { return; } @@ -474,8 +467,10 @@ protected void saveAction() { } final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(targetPathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(targetPathKey); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } fileChooser.getExtensionFilters().addAll(fileExtensionFilter); final File file = fileChooser.showSaveDialog(getMyStage()); if (file == null) { @@ -508,7 +503,7 @@ protected Void call() throws Exception { PdfTools.writePage(document, font, source.getImageFormat(), bufferedImage, ++count, total, pdfFormat, threshold, jpegQuality, isImageSize, pageNumberCheck.isSelected(), - pageWidth, pageHeight, marginSize, headerInput.getText()); + pageWidth, pageHeight, marginSize, headerInput.getText(), ditherCheck.isSelected()); } } document.save(file); @@ -526,7 +521,7 @@ public void run() { if (!fail && file.exists()) { popInformation(AppVaribles.getMessage("Successful")); if (viewCheck.isSelected()) { - OpenFile.openTarget(getClass(), null, file.getAbsolutePath()); + FxmlStage.openTarget(getClass(), null, file.getAbsolutePath()); } } else { popError(AppVaribles.getMessage("ImageCombinePdfFail")); diff --git a/MyBox/src/main/java/mara/mybox/controller/LoadingController.java b/MyBox/src/main/java/mara/mybox/controller/LoadingController.java index 41dfb43a6..7c90a9356 100644 --- a/MyBox/src/main/java/mara/mybox/controller/LoadingController.java +++ b/MyBox/src/main/java/mara/mybox/controller/LoadingController.java @@ -6,8 +6,8 @@ import javafx.scene.control.Label; import javafx.scene.control.ProgressIndicator; import javafx.scene.control.TextArea; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.CommonValues; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.CommonValues; /** * @Author Mara diff --git a/MyBox/src/main/java/mara/mybox/controller/MainMenuController.java b/MyBox/src/main/java/mara/mybox/controller/MainMenuController.java index 77cf5b7b6..7f5afa1e4 100644 --- a/MyBox/src/main/java/mara/mybox/controller/MainMenuController.java +++ b/MyBox/src/main/java/mara/mybox/controller/MainMenuController.java @@ -1,5 +1,7 @@ package mara.mybox.controller; +import java.util.concurrent.ScheduledFuture; +import javafx.application.Platform; import javafx.event.ActionEvent; import javafx.event.Event; import javafx.event.EventHandler; @@ -9,10 +11,10 @@ import javafx.scene.control.RadioMenuItem; import javafx.scene.layout.Pane; import javafx.stage.Stage; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.CommonValues; -import static mara.mybox.objects.AppVaribles.logger; -import static mara.mybox.objects.AppVaribles.getUserConfigValue; +import mara.mybox.value.AppVaribles; +import mara.mybox.value.CommonValues; +import static mara.mybox.value.AppVaribles.getUserConfigValue; +import static mara.mybox.value.AppVaribles.logger; /** * @Author Mara @@ -27,7 +29,8 @@ public class MainMenuController extends BaseController { @FXML private RadioMenuItem chineseMenuItem, englishMenuItem; @FXML - private RadioMenuItem replaceWhiteMenu, replaceBlackMenu, pdf500mbRadio, pdf1gbRadio, pdf2gbRadio, pdfUnlimitRadio; + private RadioMenuItem replaceWhiteMenu, replaceBlackMenu, pdf500mbRadio, pdf1gbRadio, pdf2gbRadio, pdfUnlimitRadio, + font12MenuItem, font15MenuItem, font17MenuItem; @FXML private CheckMenuItem showCommentsCheck, stopAlarmCheck; @FXML @@ -54,6 +57,7 @@ private void checkSettings() { checkLanguage(); checkAlpha(); checkPdfMem(); + checkFontSize(); stopAlarmCheck.setSelected(AppVaribles.getUserConfigBoolean("StopAlarmsWhenExit")); showCommentsCheck.setSelected(AppVaribles.isShowComments()); } @@ -66,6 +70,22 @@ protected void checkLanguage() { } } + protected void checkFontSize() { + switch (AppVaribles.getPaneFontSize()) { + case 12: + font12MenuItem.setSelected(true); + break; + case 15: + font15MenuItem.setSelected(true); + break; + case 17: + font17MenuItem.setSelected(true); + break; + default: + break; + } + } + protected void checkAlpha() { if (AppVaribles.isAlphaAsBlack()) { replaceBlackMenu.setSelected(true); @@ -100,16 +120,35 @@ protected void showHome(ActionEvent event) { @FXML protected void setChinese(ActionEvent event) { AppVaribles.setLanguage("zh"); - if (parentFxml.contains("ImageManufacture") && !parentFxml.contains("ImageManufactureBatch")) { - reloadStage(CommonValues.ImageManufactureFileFxml, getParentController().getMyStage().getTitle()); - } else { - reloadStage(parentFxml, getParentController().getMyStage().getTitle()); - } + refresh(); } @FXML protected void setEnglish(ActionEvent event) { AppVaribles.setLanguage("en"); + refresh(); + } + + @FXML + protected void setFont12(ActionEvent event) { + AppVaribles.setPaneFontSize(12); + refresh(); + } + + @FXML + protected void setFont15(ActionEvent event) { + AppVaribles.setPaneFontSize(15); + refresh(); + } + + @FXML + protected void setFont17(ActionEvent event) { + AppVaribles.setPaneFontSize(17); + refresh(); + } + + @Override + public void refresh() { if (parentFxml.contains("ImageManufacture") && !parentFxml.contains("ImageManufactureBatch")) { reloadStage(CommonValues.ImageManufactureFileFxml, getParentController().getMyStage().getTitle()); } else { @@ -244,7 +283,42 @@ protected void clearSettings(ActionEvent event) { @FXML private void exit(ActionEvent event) { // This statement is internel call to close the stage, so itself can not tigger stageClosing() - closeStage(); + try { + if (!getParentController().closeStage()) { + return; + } + + if (AppVaribles.scheduledTasks != null && !AppVaribles.scheduledTasks.isEmpty()) { + if (AppVaribles.getUserConfigBoolean("StopAlarmsWhenExit")) { + for (Long key : AppVaribles.scheduledTasks.keySet()) { + ScheduledFuture future = AppVaribles.scheduledTasks.get(key); + future.cancel(true); + } + AppVaribles.scheduledTasks = null; + if (AppVaribles.executorService != null) { + AppVaribles.executorService.shutdownNow(); + AppVaribles.executorService = null; + } + } + + } else { + if (AppVaribles.scheduledTasks != null) { + AppVaribles.scheduledTasks = null; + } + if (AppVaribles.executorService != null) { + AppVaribles.executorService.shutdownNow(); + AppVaribles.executorService = null; + } + } + + if (AppVaribles.scheduledTasks == null) { + Platform.exit(); + } + + } catch (Exception e) { + logger.debug(e.toString()); + } + } @FXML @@ -313,8 +387,8 @@ private void openImageViewer(ActionEvent event) { } @FXML - private void openMultipleImagesViewer(ActionEvent event) { - reloadStage(CommonValues.ImagesViewerFxml, AppVaribles.getMessage("MultipleImagesViewer")); + private void openImagesBrowser(ActionEvent event) { + reloadStage(CommonValues.ImagesBrowserFxml, AppVaribles.getMessage("ImagesBrowser")); } @FXML @@ -360,13 +434,6 @@ private void openImageManufactureEffects(ActionEvent event) { controller.setInitTab("effects"); } - @FXML - private void openImageManufactureConvolution(ActionEvent event) { - ImageManufactureFileController controller - = (ImageManufactureFileController) reloadStage(CommonValues.ImageManufactureFileFxml, AppVaribles.getMessage("ImageManufacture")); - controller.setInitTab("convolution"); - } - @FXML private void openImageManufactureText(ActionEvent event) { ImageManufactureFileController controller @@ -434,11 +501,6 @@ private void openImageManufactureBatchEffects(ActionEvent event) { reloadStage(CommonValues.ImageManufactureBatchEffectsFxml, AppVaribles.getMessage("ImageManufactureBatchEffects")); } - @FXML - private void openImageManufactureBatchConvolution(ActionEvent event) { - reloadStage(CommonValues.ImageManufactureBatchConvolutionFxml, AppVaribles.getMessage("ImageManufactureBatchConvolution")); - } - @FXML private void openImageManufactureBatchReplaceColor(ActionEvent event) { reloadStage(CommonValues.ImageManufactureBatchReplaceColorFxml, AppVaribles.getMessage("ImageManufactureBatchReplaceColor")); @@ -514,6 +576,11 @@ private void openImagesBlend(ActionEvent event) { reloadStage(CommonValues.ImagesBlendFxml, AppVaribles.getMessage("ImagesBlend")); } + @FXML + private void openImageStatistic(ActionEvent event) { + reloadStage(CommonValues.ImageStatisticFxml, AppVaribles.getMessage("ImageStatistic")); + } + @FXML private void openConvolutionKernelManager(ActionEvent event) { reloadStage(CommonValues.ConvolutionKernelManagerFxml, AppVaribles.getMessage("ConvolutionKernelManager")); @@ -585,8 +652,8 @@ private void openFileMerge(ActionEvent event) { } @FXML - private void openSnapScreen(ActionEvent event) { - reloadStage(CommonValues.SnapScreenFxml, AppVaribles.getMessage("SnapScreen")); + private void openRecordImages(ActionEvent event) { + reloadStage(CommonValues.RecordImagesInSystemClipboardFxml, AppVaribles.getMessage("RecordImagesInSystemClipBoard")); } @FXML @@ -597,12 +664,12 @@ private void openWeiboSnap(ActionEvent event) { @FXML private void showAbout(ActionEvent event) { - openStage(CommonValues.AboutFxml, true); + openStage(CommonValues.AboutFxml, false); } @FXML private void settingsAction(ActionEvent event) { - BaseController c = openStage(CommonValues.SettingsFxml, true); + BaseController c = openStage(CommonValues.SettingsFxml, false); c.setParentController(parentController); c.setParentFxml(parentFxml); } diff --git a/MyBox/src/main/java/mara/mybox/controller/MyBoxController.java b/MyBox/src/main/java/mara/mybox/controller/MyBoxController.java index 565405beb..2e61a4063 100644 --- a/MyBox/src/main/java/mara/mybox/controller/MyBoxController.java +++ b/MyBox/src/main/java/mara/mybox/controller/MyBoxController.java @@ -12,11 +12,11 @@ import javafx.scene.control.SeparatorMenuItem; import javafx.scene.input.MouseEvent; import javafx.scene.layout.VBox; -import mara.mybox.objects.AlarmClock; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.scheduledTasks; -import mara.mybox.objects.CommonValues; -import static mara.mybox.objects.AppVaribles.logger; +import mara.mybox.data.AlarmClock; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.scheduledTasks; +import mara.mybox.value.CommonValues; +import static mara.mybox.value.AppVaribles.logger; /** * @Author Mara @@ -177,11 +177,11 @@ public void handle(ActionEvent event) { } }); - MenuItem imagesViewer = new MenuItem(AppVaribles.getMessage("MultipleImagesViewer")); - imagesViewer.setOnAction(new EventHandler() { + MenuItem imagesBrowser = new MenuItem(AppVaribles.getMessage("ImagesBrowser")); + imagesBrowser.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { - reloadStage(CommonValues.ImagesViewerFxml, AppVaribles.getMessage("MultipleImagesViewer")); + reloadStage(CommonValues.ImagesBrowserFxml, AppVaribles.getMessage("ImagesBrowser")); } }); @@ -209,6 +209,14 @@ public void handle(ActionEvent event) { } }); + MenuItem imageStatistic = new MenuItem(AppVaribles.getMessage("ImageStatistic")); + imageStatistic.setOnAction(new EventHandler() { + @Override + public void handle(ActionEvent event) { + reloadStage(CommonValues.ImageStatisticFxml, AppVaribles.getMessage("ImageStatistic")); + } + }); + MenuItem convolutionKernelManager = new MenuItem(AppVaribles.getMessage("ConvolutionKernelManager")); convolutionKernelManager.setOnAction(new EventHandler() { @Override @@ -240,10 +248,12 @@ public void handle(ActionEvent event) { Menu mergeMenu = initImageMergeMenu(); imageMenu = new ContextMenu(); - imageMenu.getItems().addAll(ImageManufacture, manufactureSubMenu, manufactureBatchMenu, new SeparatorMenuItem(), + imageMenu.getItems().addAll( + imageViewer, imagesBrowser, new SeparatorMenuItem(), + ImageManufacture, manufactureSubMenu, manufactureBatchMenu, new SeparatorMenuItem(), framesMenu, new SeparatorMenuItem(), mergeMenu, new SeparatorMenuItem(), partMenu, new SeparatorMenuItem(), imageConverter, imageConverterBatch, new SeparatorMenuItem(), - imageViewer, imagesViewer, new SeparatorMenuItem(), + // imageStatistic, new SeparatorMenuItem(), convolutionKernelManager, colorPalette, pixelsCalculator); } @@ -289,16 +299,6 @@ public void handle(ActionEvent event) { } }); - MenuItem imageConvolutionMenu = new MenuItem(AppVaribles.getMessage("Convolution")); - imageConvolutionMenu.setOnAction(new EventHandler() { - @Override - public void handle(ActionEvent event) { - ImageManufactureFileController controller - = (ImageManufactureFileController) reloadStage(CommonValues.ImageManufactureFileFxml, AppVaribles.getMessage("ImageManufacture")); - controller.setInitTab("convolution"); - } - }); - MenuItem imageTextMenu = new MenuItem(AppVaribles.getMessage("Text")); imageTextMenu.setOnAction(new EventHandler() { @Override @@ -361,7 +361,7 @@ public void handle(ActionEvent event) { Menu manufactureSubMenu = new Menu(AppVaribles.getMessage("ImageManufactureSub")); manufactureSubMenu.getItems().addAll(imageSizeMenu, imageCropMenu, imageColorMenu, imageEffectsMenu, - imageConvolutionMenu, imageTextMenu, imageCoverMenu, imageArcMenu, imageShadowMenu, + imageTextMenu, imageCoverMenu, imageArcMenu, imageShadowMenu, imageTransformMenu, imageMarginsMenu); return manufactureSubMenu; @@ -393,14 +393,6 @@ public void handle(ActionEvent event) { } }); - MenuItem imageConvolutionMenu = new MenuItem(AppVaribles.getMessage("Convolution")); - imageConvolutionMenu.setOnAction(new EventHandler() { - @Override - public void handle(ActionEvent event) { - reloadStage(CommonValues.ImageManufactureBatchConvolutionFxml, AppVaribles.getMessage("ImageManufactureBatchConvolution")); - } - }); - MenuItem imageEffectsMenu = new MenuItem(AppVaribles.getMessage("Effects")); imageEffectsMenu.setOnAction(new EventHandler() { @Override @@ -467,7 +459,7 @@ public void handle(ActionEvent event) { Menu manufactureBatchMenu = new Menu(AppVaribles.getMessage("ImageManufactureBatch")); manufactureBatchMenu.getItems().addAll(imageSizeMenu, imageCropMenu, imageColorMenu, imageEffectsMenu, - imageConvolutionMenu, imageReplaceColorMenu, imageTextMenu, imageArcMenu, imageShadowMenu, imageTransformMenu, + imageReplaceColorMenu, imageTextMenu, imageArcMenu, imageShadowMenu, imageTransformMenu, imageCutMarginsMenu, imageAddMarginsMenu); return manufactureBatchMenu; @@ -642,11 +634,11 @@ public void handle(ActionEvent event) { } }); - MenuItem snapScreen = new MenuItem(AppVaribles.getMessage("SnapScreen")); - snapScreen.setOnAction(new EventHandler() { + MenuItem recordImages = new MenuItem(AppVaribles.getMessage("RecordImagesInSystemClipBoard")); + recordImages.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { - reloadStage(CommonValues.SnapScreenFxml, AppVaribles.getMessage("SnapScreen")); + reloadStage(CommonValues.RecordImagesInSystemClipboardFxml, AppVaribles.getMessage("RecordImagesInSystemClipBoard")); } }); @@ -663,7 +655,7 @@ public void handle(ActionEvent event) { textEditer, textEncodingBatch, textLineBreakBatch, new SeparatorMenuItem(), bytesEditer, fileCut, fileMerge, new SeparatorMenuItem(), filesRename, filesArrangement, dirSynchronize, new SeparatorMenuItem(), - alarmClock); + recordImages, alarmClock); } private void initFileToolsMenu() { @@ -804,7 +796,7 @@ void showLanguageMenu(MouseEvent event) { @FXML private void showAbout(MouseEvent event) { - openStage(CommonValues.AboutFxml, true); + openStage(CommonValues.AboutFxml, false); imageMenu.hide(); fileMenu.hide(); desktopMenu.hide(); diff --git a/MyBox/src/main/java/mara/mybox/controller/OperationController.java b/MyBox/src/main/java/mara/mybox/controller/OperationController.java index 0499f56d6..f3afb0ad9 100644 --- a/MyBox/src/main/java/mara/mybox/controller/OperationController.java +++ b/MyBox/src/main/java/mara/mybox/controller/OperationController.java @@ -16,8 +16,8 @@ import javafx.scene.control.Tooltip; import javafx.scene.text.Font; import mara.mybox.fxml.FxmlTools; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.getMessage; /** * FXML Controller class @@ -27,19 +27,11 @@ public class OperationController extends BaseController { @FXML - protected Button startButton; + protected Button pauseButton, openTargetButton; @FXML - protected Button pauseButton; + protected ProgressBar progressBar, fileProgressBar; @FXML - protected ProgressBar progressBar; - @FXML - protected Label progressValue; - @FXML - protected Button openTargetButton; - @FXML - protected ProgressBar fileProgressBar; - @FXML - protected Label fileProgressValue; + protected Label progressValue, fileProgressValue; @FXML protected CheckBox miaoCheck; @@ -62,9 +54,9 @@ public void changed(ObservableValue ov, Boolean oldValue, Boolean newValue) { @FXML @Override - protected void startProcess(ActionEvent event) { + public void startAction() { if (parentController != null) { - parentController.startProcess(event); + parentController.startAction(); } } @@ -72,7 +64,7 @@ protected void startProcess(ActionEvent event) { @Override protected void pauseProcess(ActionEvent event) { if (parentController != null) { - parentController.startProcess(event); + parentController.startAction(); } } diff --git a/MyBox/src/main/java/mara/mybox/controller/PdfBaseController.java b/MyBox/src/main/java/mara/mybox/controller/PdfBaseController.java index 66b43f01a..dd5f27e0c 100644 --- a/MyBox/src/main/java/mara/mybox/controller/PdfBaseController.java +++ b/MyBox/src/main/java/mara/mybox/controller/PdfBaseController.java @@ -9,11 +9,11 @@ import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.scene.layout.Pane; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.FileInformation; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.value.CommonValues; +import mara.mybox.data.FileInformation; import mara.mybox.tools.DateTools; import mara.mybox.tools.FileTools; import mara.mybox.fxml.FxmlTools; @@ -51,10 +51,13 @@ protected class ProcessParameters { public PdfBaseController() { targetPathKey = "PdfTargetPath"; + sourcePathKey = "PdfSourcePath"; + fileExtensionFilter = CommonValues.PdfExtensionFilter; + creatSubdirKey = "PdfCreatSubdir"; fillZeroKey = "PdfFillZero"; previewKey = "PdfPreview"; - sourcePathKey = "PdfSourcePath"; + appendColorKey = "PdfAppendColor"; appendCompressionTypeKey = "PdfAppendCompressionType"; appendDensityKey = "PdfAppendDensity"; @@ -63,8 +66,6 @@ public PdfBaseController() { PdfSourceFromKey = "PdfSourceFromKey"; PdfSourceToKey = "PdfSourceToKey"; - fileExtensionFilter = CommonValues.PdfExtensionFilter; - } @Override @@ -96,13 +97,13 @@ protected void sourceFileChanged(final File file) { targetSelectionController.targetPrefixInput.setText(FileTools.getFilePrefix(filename)); } if (targetSelectionController.targetPathInput != null && targetSelectionController.targetPathInput.getText().isEmpty()) { - targetSelectionController.targetPathInput.setText(AppVaribles.getUserConfigValue(targetPathKey, CommonValues.UserFilePath)); + targetSelectionController.targetPathInput.setText(AppVaribles.getUserConfigPath(targetPathKey).getAbsolutePath()); } } @FXML @Override - protected void startProcess(ActionEvent event) { + public void startAction() { isPreview = false; makeActualParameters(); currentParameters = actualParameters; @@ -341,7 +342,7 @@ public void handle(ActionEvent event) { AppVaribles.getMessage("TextEditer"), false, true); controller.openFile(new File(finalTargetName)); } else { - openImageManufacture(finalTargetName); + openImageViewer(finalTargetName); } } else if (actualParameters.targetPath != null) { Desktop.getDesktop().browse(new File(actualParameters.targetPath).toURI()); @@ -362,7 +363,7 @@ public void handle(ActionEvent event) { operationBarController.pauseButton.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { - startProcess(event); + startAction(); } }); paraBox.setDisable(true); @@ -371,7 +372,7 @@ public void handle(ActionEvent event) { operationBarController.startButton.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { - startProcess(event); + startAction(); } }); operationBarController.pauseButton.setVisible(false); diff --git a/MyBox/src/main/java/mara/mybox/controller/PdfCompressImagesBatchController.java b/MyBox/src/main/java/mara/mybox/controller/PdfCompressImagesBatchController.java index 7c49d9cb5..e53d73c8b 100644 --- a/MyBox/src/main/java/mara/mybox/controller/PdfCompressImagesBatchController.java +++ b/MyBox/src/main/java/mara/mybox/controller/PdfCompressImagesBatchController.java @@ -5,6 +5,7 @@ */ package mara.mybox.controller; +import mara.mybox.fxml.FxmlStage; import java.awt.Desktop; import java.io.File; import java.util.ArrayList; @@ -18,17 +19,21 @@ import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.scene.control.Button; +import javafx.scene.control.RadioButton; import javafx.scene.control.SelectionMode; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; +import javafx.scene.control.TextField; +import javafx.scene.control.Toggle; +import javafx.scene.control.ToggleGroup; import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.input.MouseEvent; import javafx.stage.FileChooser; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.FileInformation; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.AppVaribles; +import mara.mybox.data.FileInformation; import static mara.mybox.fxml.FxmlTools.badStyle; +import mara.mybox.tools.FileTools; /** * FXML Controller class @@ -37,12 +42,27 @@ */ public class PdfCompressImagesBatchController extends PdfCompressImagesController { + protected int targetExistType; + @FXML private TableView sourceTable; @FXML private TableColumn fileColumn, modifyTimeColumn, sizeColumn, createTimeColumn; @FXML - protected Button addButton, clearButton, openButton, deleteButton, upButton, downButton, insertButton; + protected Button addButton, clearButton, openButton, upButton, downButton, insertButton; + @FXML + protected ToggleGroup targetExistGroup; + @FXML + protected RadioButton targetReplaceRadio, targetRenameRadio, targetSkipRadio; + @FXML + protected TextField targetSuffixInput; + + protected static class TargetExistType { + + public static int Rename = 0; + public static int Replace = 1; + public static int Skip = 2; + } public PdfCompressImagesBatchController() { @@ -130,7 +150,34 @@ public void changed(ObservableValue observable, String oldValu } } }); - targetPathInput.setText(AppVaribles.getUserConfigValue(targetPathKey, CommonValues.UserFilePath)); + targetPathInput.setText(AppVaribles.getUserConfigPath(targetPathKey).getAbsolutePath()); + + targetExistGroup.selectedToggleProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue ov, + Toggle old_toggle, Toggle new_toggle) { + checkTargetExistType(); + } + }); + checkTargetExistType(); + + } + + protected void checkTargetExistType() { + targetSuffixInput.setStyle(null); + RadioButton selected = (RadioButton) targetExistGroup.getSelectedToggle(); + if (selected.equals(targetReplaceRadio)) { + targetExistType = TargetExistType.Replace; + + } else if (selected.equals(targetRenameRadio)) { + targetExistType = TargetExistType.Rename; + if (targetSuffixInput.getText() == null || targetSuffixInput.getText().trim().isEmpty()) { + targetSuffixInput.setStyle(badStyle); + } + + } else if (selected.equals(targetSkipRadio)) { + targetExistType = TargetExistType.Skip; + } } @FXML @@ -151,8 +198,10 @@ void insertAction(ActionEvent event) { private void addAction(int index) { try { final FileChooser fileChooser = new FileChooser(); - File defaultPath = new File(AppVaribles.getUserConfigPath(PdfCompressImagesSourcePathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(defaultPath); + File defaultPath = AppVaribles.getUserConfigPath(PdfCompressImagesSourcePathKey); + if (defaultPath.exists()) { + fileChooser.setInitialDirectory(defaultPath); + } fileChooser.getExtensionFilters().addAll(fileExtensionFilter); List files = fileChooser.showOpenMultipleDialog(getMyStage()); @@ -181,7 +230,8 @@ private void addAction(int index) { } @FXML - private void deleteAction(ActionEvent event) { + @Override + public void deleteAction() { List selected = new ArrayList<>(); selected.addAll(sourceTable.getSelectionModel().getSelectedIndices()); if (selected.isEmpty()) { @@ -216,7 +266,7 @@ private void openAction() { } FileInformation info = sourceFilesInformation.get(index); - OpenFile.openTarget(getClass(), null, info.getFile().getAbsolutePath()); + FxmlStage.openTarget(getClass(), null, info.getFile().getAbsolutePath()); } } @@ -293,6 +343,23 @@ protected void makeMoreParameters() { } + @Override + protected void makeTargetFile(File file) { + String filename = FileTools.getFileName(file.getName()); + targetFile = new File(targetPath.getAbsolutePath() + File.separator + filename); + if (targetExistType == TargetExistType.Rename) { + while (targetFile.exists()) { + filename = FileTools.getFilePrefix(filename) + + targetSuffixInput.getText().trim() + "." + FileTools.getFileSuffix(filename); + targetFile = new File(targetPath.getAbsolutePath() + File.separator + filename); + } + } else if (targetExistType == TargetExistType.Skip) { + if (targetFile.exists()) { + targetFile = null; + } + } + } + @FXML @Override protected void openTarget(ActionEvent event) { diff --git a/MyBox/src/main/java/mara/mybox/controller/PdfCompressImagesController.java b/MyBox/src/main/java/mara/mybox/controller/PdfCompressImagesController.java index d21631534..13abdeec7 100644 --- a/MyBox/src/main/java/mara/mybox/controller/PdfCompressImagesController.java +++ b/MyBox/src/main/java/mara/mybox/controller/PdfCompressImagesController.java @@ -1,5 +1,6 @@ package mara.mybox.controller; +import mara.mybox.fxml.FxmlStage; import java.awt.image.BufferedImage; import java.io.File; import java.util.Arrays; @@ -13,18 +14,22 @@ import javafx.concurrent.Task; import javafx.event.ActionEvent; import javafx.fxml.FXML; +import javafx.scene.control.CheckBox; import javafx.scene.control.ComboBox; import javafx.scene.control.RadioButton; import javafx.scene.control.TextField; import javafx.scene.control.Toggle; import javafx.scene.control.ToggleGroup; +import javafx.scene.control.Tooltip; import javafx.stage.FileChooser; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.image.ImageGrayTools; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.CommonValues; +import mara.mybox.fxml.FxmlTools; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.AppVaribles; +import mara.mybox.value.CommonValues; import mara.mybox.tools.FileTools; import static mara.mybox.fxml.FxmlTools.badStyle; +import mara.mybox.image.ImageBinary; +import static mara.mybox.value.AppVaribles.getMessage; import org.apache.pdfbox.cos.COSName; import org.apache.pdfbox.multipdf.Splitter; import org.apache.pdfbox.pdmodel.PDDocument; @@ -55,6 +60,8 @@ public class PdfCompressImagesController extends PdfBaseController { protected ComboBox jpegBox; @FXML protected TextField thresholdInput, authorInput; + @FXML + protected CheckBox ditherCheck; public PdfCompressImagesController() { PdfCompressImagesSourcePathKey = "PdfCompressImagesSourcePathKey"; @@ -122,6 +129,7 @@ public void changed(ObservableValue observable, String oldValu } }); checkThreshold(); + FxmlTools.setComments(ditherCheck, new Tooltip(getMessage("DitherComments"))); authorInput.textProperty().addListener(new ChangeListener() { @Override @@ -171,7 +179,7 @@ protected void checkThreshold() { return; } threshold = Integer.valueOf(thresholdInput.getText()); - if (threshold >= 0 && threshold <= 100) { + if (threshold >= 0 && threshold <= 255) { thresholdInput.setStyle(null); } else { threshold = -1; @@ -216,8 +224,10 @@ protected void sourceFileChanged(final File file) { protected void selectTargetFile(ActionEvent event) { try { final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(targetPathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(targetPathKey); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } fileChooser.getExtensionFilters().addAll(fileExtensionFilter); final File file = fileChooser.showSaveDialog(getMyStage()); if (file == null) { @@ -265,11 +275,14 @@ protected Void call() { currentParameters.sourceFile = file; updateInterface("StartFile"); if (currentParameters.isBatch) { - targetFile = new File(targetPath.getAbsolutePath() + File.separator - + FileTools.getFileName(file.getName())); + makeTargetFile(file); + } + if (targetFile != null) { + handleCurrentFile(); + } else { + updateProgress(0, 0); + updateMessage("0"); } - - handleCurrentFile(); markFileHandled(currentParameters.currentFileIndex); if (isCancelled() || isPreview) { @@ -291,15 +304,15 @@ protected Void call() { @Override public void run() { try { - if (!fail && targetFile.exists()) { + if (!fail && targetFile != null && targetFile.exists()) { if (currentParameters.isBatch) { - OpenFile.openTarget(getClass(), null, targetPath.getAbsolutePath()); + FxmlStage.openTarget(getClass(), null, targetPath.getAbsolutePath()); } else { - OpenFile.openTarget(getClass(), null, targetFile.getAbsolutePath()); + FxmlStage.openTarget(getClass(), null, targetFile.getAbsolutePath()); } operationBarController.openTargetButton.setDisable(false); } else { - popError(AppVaribles.getMessage("ImageCombinePdfFail")); + popError(AppVaribles.getMessage("Failed")); } } catch (Exception e) { logger.error(e.toString()); @@ -384,13 +397,12 @@ protected void handleCurrentPage(PDPage pdPage) { BufferedImage sourceImage = pdxObject.getImage(); PDImageXObject newObject = null; if (format == PdfImageFormat.Tiff) { - BufferedImage newImage; - if (threshold < 0) { - newImage = ImageGrayTools.color2Binary(sourceImage); - } else { - newImage = ImageGrayTools.color2BinaryWithPercentage(sourceImage, threshold); - } + ImageBinary imageBinary = new ImageBinary(sourceImage, threshold); + imageBinary.setIsDithering(ditherCheck.isSelected()); + BufferedImage newImage = imageBinary.operate(); + newImage = ImageBinary.byteBinary(newImage); newObject = CCITTFactory.createFromImage(document, newImage); + } else if (format == PdfImageFormat.Jpeg) { newObject = JPEGFactory.createFromImage(document, sourceImage, jpegQuality / 100f); } @@ -438,6 +450,11 @@ protected void failed() { } } + protected void makeTargetFile(File file) { + targetFile = new File(targetPath.getAbsolutePath() + File.separator + + FileTools.getFileName(file.getName())); + } + protected File getTargetFile() { return targetFile; } @@ -450,7 +467,7 @@ protected void openTarget(ActionEvent event) { return; } operationBarController.openTargetButton.setDisable(false); - OpenFile.openTarget(getClass(), null, targetFile.getAbsolutePath()); + FxmlStage.openTarget(getClass(), null, targetFile.getAbsolutePath()); } } diff --git a/MyBox/src/main/java/mara/mybox/controller/PdfConvertAttributesController.java b/MyBox/src/main/java/mara/mybox/controller/PdfConvertAttributesController.java index dcdbb387b..ca6186aa9 100644 --- a/MyBox/src/main/java/mara/mybox/controller/PdfConvertAttributesController.java +++ b/MyBox/src/main/java/mara/mybox/controller/PdfConvertAttributesController.java @@ -13,9 +13,9 @@ import javafx.scene.control.Toggle; import javafx.scene.control.ToggleGroup; import javafx.scene.layout.HBox; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.getMessage; import mara.mybox.fxml.FxmlTools; /** diff --git a/MyBox/src/main/java/mara/mybox/controller/PdfConvertImagesBatchController.java b/MyBox/src/main/java/mara/mybox/controller/PdfConvertImagesBatchController.java index f89e25788..dc41076c5 100644 --- a/MyBox/src/main/java/mara/mybox/controller/PdfConvertImagesBatchController.java +++ b/MyBox/src/main/java/mara/mybox/controller/PdfConvertImagesBatchController.java @@ -2,9 +2,8 @@ import javafx.beans.binding.Bindings; import javafx.beans.property.SimpleBooleanProperty; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.CommonValues; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.AppVaribles; import static mara.mybox.fxml.FxmlTools.badStyle; /** @@ -38,7 +37,7 @@ protected void initializeNext2() { ); if (targetSelectionController.targetPathInput != null && targetSelectionController.targetPathInput.getText().isEmpty()) { - targetSelectionController.targetPathInput.setText(AppVaribles.getUserConfigValue("pdfTargetPath", CommonValues.UserFilePath)); + targetSelectionController.targetPathInput.setText(AppVaribles.getUserConfigPath("pdfTargetPath").getAbsolutePath()); } } catch (Exception e) { logger.error(e.toString()); diff --git a/MyBox/src/main/java/mara/mybox/controller/PdfConvertImagesController.java b/MyBox/src/main/java/mara/mybox/controller/PdfConvertImagesController.java index 3ad15de1c..1358b2e63 100644 --- a/MyBox/src/main/java/mara/mybox/controller/PdfConvertImagesController.java +++ b/MyBox/src/main/java/mara/mybox/controller/PdfConvertImagesController.java @@ -6,13 +6,13 @@ import javafx.beans.binding.Bindings; import javafx.beans.property.SimpleBooleanProperty; import javafx.concurrent.Task; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.ImageAttributes; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.AppVaribles; +import mara.mybox.data.ImageAttributes; import mara.mybox.tools.FileTools; import static mara.mybox.fxml.FxmlTools.badStyle; -import mara.mybox.image.ImageGrayTools; -import mara.mybox.imagefile.ImageFileWriters; +import mara.mybox.image.ImageBinary; +import mara.mybox.image.file.ImageFileWriters; import mara.mybox.tools.ValueTools; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.rendering.ImageType; @@ -192,12 +192,29 @@ protected void convertCurrentPage(PDFRenderer renderer) { if (attributes.getBinaryConversion() == ImageAttributes.BinaryConversion.BINARY_THRESHOLD && attributes.getThreshold() >= 0) { image = renderer.renderImageWithDPI(currentParameters.currentPage, attributes.getDensity(), ImageType.RGB); - image = ImageGrayTools.color2BinaryWithPercentage(image, attributes.getThreshold()); + ImageBinary imageBinary = new ImageBinary(image, attributes.getThreshold()); + imageBinary.setIsDithering(attributes.isIsDithering()); + image = imageBinary.operate(); + image = ImageBinary.byteBinary(image); + } else if (attributes.getBinaryConversion() == ImageAttributes.BinaryConversion.BINARY_OTSU) { image = renderer.renderImageWithDPI(currentParameters.currentPage, attributes.getDensity(), ImageType.RGB); - image = ImageGrayTools.color2BinaryByCalculation(image); + ImageBinary imageBinary = new ImageBinary(image, -1); + imageBinary.setCalculate(true); + imageBinary.setIsDithering(attributes.isIsDithering()); + image = imageBinary.operate(); + image = ImageBinary.byteBinary(image); + } else { - image = renderer.renderImageWithDPI(currentParameters.currentPage, attributes.getDensity(), ImageType.BINARY); + if (attributes.isIsDithering()) { + image = renderer.renderImageWithDPI(currentParameters.currentPage, attributes.getDensity(), ImageType.RGB); + ImageBinary imageBinary = new ImageBinary(image, -1); + imageBinary.setIsDithering(true); + image = imageBinary.operate(); + image = ImageBinary.byteBinary(image); + } else { + image = renderer.renderImageWithDPI(currentParameters.currentPage, attributes.getDensity(), ImageType.BINARY); + } } } else { image = renderer.renderImageWithDPI(currentParameters.currentPage, attributes.getDensity(), attributes.getColorSpace()); @@ -212,7 +229,7 @@ protected String makeFilename() { ImageAttributes attributes = pdfConvertAttributesController.getAttributes(); String pageNumber = currentParameters.currentNameNumber + ""; if (currentParameters.fill) { - pageNumber = ValueTools.fillNumber(currentParameters.currentNameNumber, currentParameters.acumDigit); + pageNumber = ValueTools.fillLeftZero(currentParameters.currentNameNumber, currentParameters.acumDigit); } String fname = currentParameters.targetPath + "/" + currentParameters.targetPrefix + "_" + pageNumber; if (currentParameters.aColor) { diff --git a/MyBox/src/main/java/mara/mybox/controller/PdfExtractImagesBatchController.java b/MyBox/src/main/java/mara/mybox/controller/PdfExtractImagesBatchController.java index 3eb3ca4d9..7c90f9d01 100644 --- a/MyBox/src/main/java/mara/mybox/controller/PdfExtractImagesBatchController.java +++ b/MyBox/src/main/java/mara/mybox/controller/PdfExtractImagesBatchController.java @@ -3,9 +3,8 @@ import javafx.beans.binding.Bindings; import javafx.fxml.FXML; import javafx.scene.control.ScrollPane; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.CommonValues; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.AppVaribles; import static mara.mybox.fxml.FxmlTools.badStyle; /** @@ -38,7 +37,7 @@ protected void initializeNext2() { ); if (targetSelectionController.targetPathInput != null && targetSelectionController.targetPathInput.getText().isEmpty()) { - targetSelectionController.targetPathInput.setText(AppVaribles.getUserConfigValue("pdfTargetPath", CommonValues.UserFilePath)); + targetSelectionController.targetPathInput.setText(AppVaribles.getUserConfigPath("pdfTargetPath").getAbsolutePath()); } } catch (Exception e) { logger.error(e.toString()); diff --git a/MyBox/src/main/java/mara/mybox/controller/PdfExtractImagesController.java b/MyBox/src/main/java/mara/mybox/controller/PdfExtractImagesController.java index 13a6d7a75..9de5a2cd4 100644 --- a/MyBox/src/main/java/mara/mybox/controller/PdfExtractImagesController.java +++ b/MyBox/src/main/java/mara/mybox/controller/PdfExtractImagesController.java @@ -12,11 +12,11 @@ import javafx.concurrent.Task; import javafx.fxml.FXML; import javafx.scene.control.CheckBox; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.AppVaribles; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.AppVaribles; import mara.mybox.tools.FileTools; import static mara.mybox.fxml.FxmlTools.badStyle; -import mara.mybox.imagefile.ImageFileWriters; +import mara.mybox.image.file.ImageFileWriters; import mara.mybox.tools.ValueTools; import org.apache.pdfbox.cos.COSName; import org.apache.pdfbox.pdmodel.PDDocument; @@ -228,7 +228,7 @@ protected void failed() { protected String makeFilename(String suffix, int page, int index) { String pageNumber = currentParameters.currentNameNumber + ""; if (currentParameters.fill) { - pageNumber = ValueTools.fillNumber(currentParameters.currentNameNumber, currentParameters.acumDigit); + pageNumber = ValueTools.fillLeftZero(currentParameters.currentNameNumber, currentParameters.acumDigit); } String fname = currentParameters.targetPath + "/" + currentParameters.targetPrefix + "_" + pageNumber; if (appendPageNumber.isSelected()) { diff --git a/MyBox/src/main/java/mara/mybox/controller/PdfExtractTextsBatchController.java b/MyBox/src/main/java/mara/mybox/controller/PdfExtractTextsBatchController.java index cd926c53f..07887ca0a 100644 --- a/MyBox/src/main/java/mara/mybox/controller/PdfExtractTextsBatchController.java +++ b/MyBox/src/main/java/mara/mybox/controller/PdfExtractTextsBatchController.java @@ -3,9 +3,8 @@ import javafx.beans.binding.Bindings; import javafx.fxml.FXML; import javafx.scene.control.ScrollPane; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.CommonValues; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.AppVaribles; import static mara.mybox.fxml.FxmlTools.badStyle; /** @@ -35,7 +34,7 @@ protected void initializeNext2() { ); if (targetSelectionController.targetPathInput != null && targetSelectionController.targetPathInput.getText().isEmpty()) { - targetSelectionController.targetPathInput.setText(AppVaribles.getUserConfigValue("pdfTargetPath", CommonValues.UserFilePath)); + targetSelectionController.targetPathInput.setText(AppVaribles.getUserConfigPath("pdfTargetPath").getAbsolutePath()); } } catch (Exception e) { logger.error(e.toString()); diff --git a/MyBox/src/main/java/mara/mybox/controller/PdfExtractTextsController.java b/MyBox/src/main/java/mara/mybox/controller/PdfExtractTextsController.java index e680d72d9..7d4b3f865 100644 --- a/MyBox/src/main/java/mara/mybox/controller/PdfExtractTextsController.java +++ b/MyBox/src/main/java/mara/mybox/controller/PdfExtractTextsController.java @@ -8,8 +8,8 @@ import javafx.fxml.FXML; import javafx.scene.control.CheckBox; import javafx.scene.control.TextField; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.AppVaribles; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.AppVaribles; import mara.mybox.tools.FileTools; import static mara.mybox.fxml.FxmlTools.badStyle; import org.apache.pdfbox.pdmodel.PDDocument; diff --git a/MyBox/src/main/java/mara/mybox/controller/PdfInformationController.java b/MyBox/src/main/java/mara/mybox/controller/PdfInformationController.java index b9c0c31dc..2e5211483 100644 --- a/MyBox/src/main/java/mara/mybox/controller/PdfInformationController.java +++ b/MyBox/src/main/java/mara/mybox/controller/PdfInformationController.java @@ -1,12 +1,12 @@ package mara.mybox.controller; import java.io.File; -import mara.mybox.objects.PdfInformation; +import mara.mybox.data.PdfInformation; import javafx.fxml.FXML; import javafx.scene.control.TextField; import mara.mybox.tools.DateTools; import static mara.mybox.tools.FileTools.showFileSize; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.logger; /** * @Author Mara diff --git a/MyBox/src/main/java/mara/mybox/controller/PdfMergeController.java b/MyBox/src/main/java/mara/mybox/controller/PdfMergeController.java index 48d6d2c9b..376954241 100644 --- a/MyBox/src/main/java/mara/mybox/controller/PdfMergeController.java +++ b/MyBox/src/main/java/mara/mybox/controller/PdfMergeController.java @@ -1,5 +1,6 @@ package mara.mybox.controller; +import mara.mybox.fxml.FxmlStage; import java.io.File; import java.util.ArrayList; import java.util.Calendar; @@ -29,11 +30,11 @@ import javafx.scene.text.Font; import javafx.stage.FileChooser; import javafx.stage.Modality; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.FileInformation; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.value.CommonValues; +import mara.mybox.data.FileInformation; import mara.mybox.tools.FileTools; import mara.mybox.fxml.FxmlTools; import static mara.mybox.fxml.FxmlTools.badStyle; @@ -44,7 +45,7 @@ import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.interactive.action.PDActionGoTo; import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageXYZDestination; -import static mara.mybox.objects.AppVaribles.getUserConfigValue; +import static mara.mybox.value.AppVaribles.getUserConfigValue; /** * @Author Mara @@ -58,7 +59,7 @@ public class PdfMergeController extends PdfBaseController { private File targetFile; @FXML - private Button openTargetButton, saveButton; + private Button openTargetButton; @FXML private TableView sourceTable; @FXML @@ -184,8 +185,10 @@ public void changed(ObservableValue observable, String oldValu private void addAction(ActionEvent event) { try { final FileChooser fileChooser = new FileChooser(); - File defaultPath = new File(AppVaribles.getUserConfigPath(sourcePathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(defaultPath); + File defaultPath = AppVaribles.getUserConfigPath(sourcePathKey); + if (defaultPath.exists()) { + fileChooser.setInitialDirectory(defaultPath); + } fileChooser.getExtensionFilters().addAll(fileExtensionFilter); List files = fileChooser.showOpenMultipleDialog(getMyStage()); @@ -210,7 +213,8 @@ private void addAction(ActionEvent event) { } @FXML - private void deleteAction(ActionEvent event) { + @Override + public void deleteAction() { List selected = new ArrayList<>(); selected.addAll(sourceTable.getSelectionModel().getSelectedIndices()); if (selected.isEmpty()) { @@ -245,7 +249,7 @@ private void openAction() { } FileInformation info = sourceFilesInformation.get(index); - OpenFile.openTarget(getClass(), null, info.getFile().getAbsolutePath()); + FxmlStage.openTarget(getClass(), null, info.getFile().getAbsolutePath()); } } @@ -344,8 +348,10 @@ protected void mouseEnterPane(MouseEvent event) { protected void selectTargetFile(ActionEvent event) { try { final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(targetPathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(targetPathKey); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } fileChooser.getExtensionFilters().addAll(CommonValues.PdfExtensionFilter); final File file = fileChooser.showSaveDialog(getMyStage()); if (file == null) { @@ -370,11 +376,12 @@ protected void openTargetAction(ActionEvent event) { return; } openTargetButton.setDisable(false); - OpenFile.openTarget(getClass(), null, targetFile.getAbsolutePath()); + FxmlStage.openTarget(getClass(), null, targetFile.getAbsolutePath()); } @FXML - protected void saveAction(ActionEvent event) { + @Override + public void saveAction() { if (sourceFilesInformation == null || sourceFilesInformation.isEmpty() || targetFile == null) { return; @@ -387,7 +394,7 @@ protected void saveAction(ActionEvent event) { @Override protected Void call() throws Exception { try { - final MemoryUsageSetting memSettings = AppVaribles.PdfMemUsage.setTempDir(AppVaribles.getTempPathFile()); + final MemoryUsageSetting memSettings = AppVaribles.PdfMemUsage.setTempDir(AppVaribles.getUserTempPath()); PDFMergerUtility mergePdf = new PDFMergerUtility(); for (FileInformation source : sourceFilesInformation) { @@ -444,7 +451,7 @@ public void run() { public void run() { try { if (!fail && targetFile.exists()) { - OpenFile.openTarget(getClass(), null, targetFile.getAbsolutePath()); + FxmlStage.openTarget(getClass(), null, targetFile.getAbsolutePath()); openTargetButton.setDisable(false); } else { popError(errorString); diff --git a/MyBox/src/main/java/mara/mybox/controller/PdfSourceSelectionController.java b/MyBox/src/main/java/mara/mybox/controller/PdfSourceSelectionController.java index 6d0a8134b..880338b75 100644 --- a/MyBox/src/main/java/mara/mybox/controller/PdfSourceSelectionController.java +++ b/MyBox/src/main/java/mara/mybox/controller/PdfSourceSelectionController.java @@ -5,6 +5,7 @@ */ package mara.mybox.controller; +import mara.mybox.fxml.FxmlStage; import java.io.File; import javafx.application.Platform; import javafx.beans.value.ChangeListener; @@ -24,10 +25,10 @@ import javafx.stage.Stage; import javafx.stage.StageStyle; import javafx.stage.WindowEvent; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.PdfInformation; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.AppVaribles; +import mara.mybox.value.CommonValues; +import mara.mybox.data.PdfInformation; import mara.mybox.tools.FileTools; import mara.mybox.fxml.FxmlTools; import static mara.mybox.fxml.FxmlTools.badStyle; @@ -42,7 +43,7 @@ public class PdfSourceSelectionController extends BaseController { protected PdfInformation pdfInformation; @FXML - protected Button sourceSelectButton, fileInformationButton, pdfOpenButon; + protected Button sourceSelectButton, pdfOpenButon; @FXML protected TextField fromPageInput, toPageInput; @FXML @@ -97,8 +98,10 @@ public void changed(ObservableValue observable, String oldValu protected void selectSourceFile(ActionEvent event) { try { final FileChooser fileChooser = new FileChooser(); - File path = new File(AppVaribles.getUserConfigPath(parentController.sourcePathKey, CommonValues.UserFilePath)); - fileChooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(parentController.sourcePathKey); + if (path.exists()) { + fileChooser.setInitialDirectory(path); + } fileChooser.getExtensionFilters().addAll(fileExtensionFilter); File file = fileChooser.showOpenDialog(getMyStage()); if (file == null) { @@ -120,7 +123,8 @@ protected void selectSourceFile(ActionEvent event) { } @FXML - protected void showFileInformation(ActionEvent event) { + @Override + public void infoAction() { if (pdfInformation == null) { return; } @@ -159,7 +163,7 @@ protected void openPdfAction(ActionEvent event) { if (pdfInformation == null) { return; } - OpenFile.openPdfViewer(getClass(), null, pdfInformation.getFile()); + FxmlStage.openPdfViewer(getClass(), null, pdfInformation.getFile()); } public void loadPdfInformation() { @@ -167,7 +171,7 @@ public void loadPdfInformation() { return; } toPageInput.setText(""); - fileInformationButton.setDisable(true); + infoButton.setDisable(true); pdfInformation = new PdfInformation(sourceFile); task = new Task() { @@ -182,7 +186,7 @@ protected Void call() throws Exception { public void run() { if (pdfInformation != null) { toPageInput.setText(pdfInformation.getNumberOfPages() + ""); - fileInformationButton.setDisable(false); + infoButton.setDisable(false); pdfOpenButon.setDisable(false); } parentController.sourceFileChanged(sourceFile); @@ -225,12 +229,12 @@ public void setSourceSelectButton(Button sourceSelectButton) { this.sourceSelectButton = sourceSelectButton; } - public Button getFileInformationButton() { - return fileInformationButton; + public Button getInfoButton() { + return infoButton; } - public void setFileInformationButton(Button fileInformationButton) { - this.fileInformationButton = fileInformationButton; + public void setInfoButton(Button infoButton) { + this.infoButton = infoButton; } public TextField getFromPageInput() { diff --git a/MyBox/src/main/java/mara/mybox/controller/PdfSplitController.java b/MyBox/src/main/java/mara/mybox/controller/PdfSplitController.java index 2f5ccece6..4bae70080 100644 --- a/MyBox/src/main/java/mara/mybox/controller/PdfSplitController.java +++ b/MyBox/src/main/java/mara/mybox/controller/PdfSplitController.java @@ -20,10 +20,10 @@ import javafx.scene.input.MouseEvent; import javafx.scene.layout.HBox; import javafx.scene.text.Font; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.CommonValues; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.value.CommonValues; import mara.mybox.tools.FileTools; import mara.mybox.fxml.FxmlTools; import static mara.mybox.fxml.FxmlTools.badStyle; @@ -34,7 +34,7 @@ import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.interactive.action.PDActionGoTo; import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageXYZDestination; -import static mara.mybox.objects.AppVaribles.getUserConfigValue; +import static mara.mybox.value.AppVaribles.getUserConfigValue; import mara.mybox.tools.ValueTools; /** @@ -138,6 +138,10 @@ public void changed(ObservableValue observable, String oldValu tips.setFont(new Font(16)); FxmlTools.quickTooltip(pdfMemBox, tips); + tips = new Tooltip(getMessage("StartEndComments")); + tips.setFont(new Font(16)); + FxmlTools.setComments(ListInput, tips); + checkPdfMem(); } catch (Exception e) { @@ -287,7 +291,7 @@ protected void doCurrentProcess() { currentParameters.currentTotalHandled = 0; currentParameters.targetPath = new File(currentParameters.targetPath).getAbsolutePath(); - final MemoryUsageSetting memSettings = AppVaribles.PdfMemUsage.setTempDir(AppVaribles.getTempPathFile()); + final MemoryUsageSetting memSettings = AppVaribles.PdfMemUsage.setTempDir(AppVaribles.getUserTempPath()); updateInterface("Started"); task = new Task() { @@ -471,7 +475,7 @@ private void writeFiles(List docs) { info.setProducer("MyBox v" + CommonValues.AppVersion); info.setAuthor(authorInput.getText()); for (PDDocument doc : docs) { - String pageNumber = ValueTools.fillNumber(currentParameters.currentNameNumber, + String pageNumber = ValueTools.fillLeftZero(currentParameters.currentNameNumber, (filesNumber + "").length()); String fname = currentParameters.targetPrefix + "_" + pageNumber + ".pdf"; String fullname = currentParameters.targetPath + "/" + fname; diff --git a/MyBox/src/main/java/mara/mybox/controller/PdfViewController.java b/MyBox/src/main/java/mara/mybox/controller/PdfViewController.java index 0624864b5..aaa7848e7 100644 --- a/MyBox/src/main/java/mara/mybox/controller/PdfViewController.java +++ b/MyBox/src/main/java/mara/mybox/controller/PdfViewController.java @@ -10,7 +10,6 @@ import javafx.beans.value.ObservableValue; import javafx.concurrent.Task; import javafx.embed.swing.SwingFXUtils; -import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; @@ -20,8 +19,6 @@ import javafx.scene.control.ComboBox; import javafx.scene.control.Label; import javafx.scene.control.TextField; -import javafx.scene.control.ToolBar; -import javafx.scene.input.MouseEvent; import javafx.scene.layout.HBox; import javafx.scene.layout.Pane; import javafx.stage.Modality; @@ -29,10 +26,10 @@ import javafx.stage.StageStyle; import javafx.stage.WindowEvent; import static mara.mybox.fxml.FxmlTools.badStyle; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.PdfInformation; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.CommonValues; +import mara.mybox.data.PdfInformation; import mara.mybox.tools.PdfTools; import org.apache.pdfbox.rendering.ImageType; @@ -47,28 +44,26 @@ public class PdfViewController extends ImageViewerController { private PdfInformation pdfInformation; private int currentPage, currentPageTmp, percent, dpi; protected SimpleBooleanProperty infoLoaded; - private boolean isSettingValues, isTransparent; + private boolean isTransparent; @FXML - protected Label pageLabel, cropLabel; + protected Label pageLabel; @FXML - protected Button firstPageButton, perviousPageButton, nextPageButton, lastPageButton, pageGoButton; + protected Button pageGoButton; @FXML protected TextField pageInput; @FXML - protected HBox navBox; - @FXML protected ComboBox sizeBox, dpiBox; @FXML - protected CheckBox selectCheck, transCheck; + protected CheckBox transCheck; @FXML - protected ToolBar optionBar; + protected HBox pageNavBox; public PdfViewController() { sourcePathKey = "PdfSourcePath"; + TipsLabelKey = "PdfViewTips"; fileExtensionFilter = CommonValues.PdfExtensionFilter; - } @Override @@ -76,24 +71,8 @@ protected void initializeNext2() { try { infoLoaded = new SimpleBooleanProperty(false); - optionBar.disableProperty().bind(Bindings.not(infoLoaded)); - infoBar.disableProperty().bind(Bindings.not(infoLoaded)); - navBox.disableProperty().bind(Bindings.not(infoLoaded)); - opeBox.disableProperty().bind( - Bindings.isNull(imageView.imageProperty()) - ); - - selectCheck.selectedProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue ov, Boolean oldValue, Boolean newValue) { - cropLabel.setDisable(!selectCheck.isSelected()); - if (!selectCheck.isSelected()) { - selectAllAction(); - bottomLabel.setText(""); - } - } - }); - cropLabel.setDisable(!selectCheck.isSelected()); + operation1Box.disableProperty().bind(Bindings.not(infoLoaded)); + pageNavBox.disableProperty().bind(Bindings.not(infoLoaded)); transCheck.selectedProperty().addListener(new ChangeListener() { @Override @@ -156,7 +135,7 @@ public void changed(ObservableValue ov, String oldValue, String newValue) { if (isSettingValues) { return; } - if (navBox.isDisabled()) { + if (pageNavBox.isDisabled()) { currentPageTmp = 0; pageInput.setStyle(null); return; @@ -183,6 +162,24 @@ public void changed(ObservableValue ov, String oldValue, String newValue) { } } + @Override + protected void initOperation2Box() { + + operation2Box.disableProperty().bind( + Bindings.isNull(imageView.imageProperty()) + ); + + cropCheck.selectedProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue ov, Boolean oldValue, Boolean newValue) { + AppVaribles.setUserConfigValue(SelectKey, cropCheck.isSelected()); + checkSelect(); + } + }); + cropCheck.setSelected(AppVaribles.getUserConfigBoolean(SelectKey, true)); + checkSelect(); + } + private void setSize(int percent) { if (imageView.getImage() == null) { return; @@ -195,21 +192,25 @@ private void setSize(int percent) { @Override public void sourceFileChanged(final File file) { - imageView.setImage(null); - imageView.setTranslateX(0); - pdfInformation = null; - currentPage = 0; - infoLoaded.set(false); - pageInput.setText("1"); - pageLabel.setText(""); - percent = 0; - if (file == null) { - return; + try { + imageView.setImage(null); + imageView.setTranslateX(0); + pdfInformation = null; + currentPage = 0; + infoLoaded.set(false); + pageInput.setText("1"); + pageLabel.setText(""); + percent = 0; + if (file == null) { + return; + } + sourceFile = file; + pdfInformation = new PdfInformation(sourceFile); + getMyStage().setTitle(getBaseTitle() + " " + sourceFile.getAbsolutePath()); + loadPage(); + } catch (Exception e) { + logger.debug(e.toString()); } - sourceFile = file; - pdfInformation = new PdfInformation(sourceFile); - getMyStage().setTitle(getBaseTitle() + " " + sourceFile.getAbsolutePath()); - loadPage(); } public void loadInformation() { @@ -249,8 +250,8 @@ private void loadPage() { isSettingValues = true; pageInput.setText((currentPage + 1) + ""); isSettingValues = false; - perviousPageButton.setDisable(currentPage <= 0); - nextPageButton.setDisable(infoLoaded.get() && currentPage >= (pdfInformation.getNumberOfPages() - 1)); + previousButton.setDisable(currentPage <= 0); + nextButton.setDisable(infoLoaded.get() && currentPage >= (pdfInformation.getNumberOfPages() - 1)); bottomLabel.setText(""); task = new Task() { @Override @@ -269,7 +270,9 @@ public void run() { if (percent == 0) { sizeBox.getSelectionModel().select("100"); } - selectAllAction(); + fitSize(); + checkSelect(); + if (!infoLoaded.get()) { loadInformation(); } @@ -285,7 +288,8 @@ public void run() { } @FXML - protected void popPdfInformation(ActionEvent event) { + @Override + public void infoAction() { if (pdfInformation == null) { return; } @@ -320,7 +324,8 @@ public void handle(WindowEvent event) { } @FXML - protected void nextPageAction() { + @Override + public void nextAction() { if (pdfInformation == null) { return; } @@ -329,7 +334,8 @@ protected void nextPageAction() { } @FXML - protected void previousPageAction() { + @Override + public void previousAction() { if (pdfInformation == null) { return; } @@ -338,7 +344,8 @@ protected void previousPageAction() { } @FXML - protected void firstPageAction() { + @Override + public void firstAction() { if (pdfInformation == null) { return; } @@ -347,7 +354,8 @@ protected void firstPageAction() { } @FXML - protected void lastPageAction() { + @Override + public void lastAction() { if (pdfInformation == null) { return; } @@ -369,6 +377,13 @@ public void setSizeBox() { isSettingValues = false; } + @FXML + @Override + public void imageSize() { + super.imageSize(); + setSizeBox(); + } + @FXML @Override public void paneSize() { @@ -390,13 +405,4 @@ public void zoomOut() { setSizeBox(); } - @FXML - @Override - public void clickImage(MouseEvent event) { - if (!selectCheck.isSelected()) { - return; - } - super.clickImage(event); - } - } diff --git a/MyBox/src/main/java/mara/mybox/controller/PixelsCalculationController.java b/MyBox/src/main/java/mara/mybox/controller/PixelsCalculationController.java index 9de45ef86..065ea9a00 100644 --- a/MyBox/src/main/java/mara/mybox/controller/PixelsCalculationController.java +++ b/MyBox/src/main/java/mara/mybox/controller/PixelsCalculationController.java @@ -22,11 +22,11 @@ import javafx.scene.control.Toggle; import javafx.scene.control.ToggleGroup; import javafx.scene.layout.HBox; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.image.ImageConvertTools.KeepRatioType; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.ImageAttributes; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.image.ImageConvert.KeepRatioType; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.data.ImageAttributes; import mara.mybox.fxml.FxmlTools; import static mara.mybox.fxml.FxmlTools.badStyle; import mara.mybox.tools.ValueTools; diff --git a/MyBox/src/main/java/mara/mybox/controller/RecordImagesInSystemClipboardController.java b/MyBox/src/main/java/mara/mybox/controller/RecordImagesInSystemClipboardController.java new file mode 100644 index 000000000..b7d0872a7 --- /dev/null +++ b/MyBox/src/main/java/mara/mybox/controller/RecordImagesInSystemClipboardController.java @@ -0,0 +1,356 @@ +package mara.mybox.controller; + +import mara.mybox.fxml.FxmlStage; +import java.awt.image.BufferedImage; +import java.io.File; +import java.text.MessageFormat; +import java.util.Arrays; +import java.util.Timer; +import java.util.TimerTask; +import javafx.application.Platform; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.control.Button; +import javafx.scene.control.ComboBox; +import javafx.scene.control.Label; +import javafx.scene.control.RadioButton; +import javafx.scene.control.TextField; +import javafx.scene.control.TitledPane; +import javafx.scene.control.Toggle; +import javafx.scene.control.ToggleGroup; +import javafx.scene.image.Image; +import javafx.stage.DirectoryChooser; +import mara.mybox.fxml.image.ImageTools; +import static mara.mybox.fxml.FxmlTools.badStyle; +import mara.mybox.image.ImageBinary; +import mara.mybox.image.ImageConvert; +import mara.mybox.image.file.ImageFileWriters; +import mara.mybox.value.AppVaribles; +import mara.mybox.value.CommonValues; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.data.ImageAttributes; +import mara.mybox.tools.DateTools; +import mara.mybox.tools.SystemTools; +import mara.mybox.tools.ValueTools; + +/** + * @Author Mara + * @CreateDate 2019-1-22 + * @Description + * @License Apache License Version 2.0 + */ +public class RecordImagesInSystemClipboardController extends BaseController { + + private int recordedNumber; + private ImageType imageType; + private int jpegQuality, threshold; + private String filePrefix; + private RecordType recordType; + private Image lastImage; + private boolean isHandling; + + private enum RecordType { + Save, View, SaveAndView + } + + private enum ImageType { + PNG, JPG, TIFF + } + + @FXML + private Button openButton; + @FXML + protected TitledPane targetPane, optionsPane; + @FXML + protected RadioButton saveRadio, viewRadio, saveAndViewRadio; + @FXML + protected Label recordLabel; + @FXML + protected ComboBox jpegBox; + @FXML + protected ToggleGroup recordTypeGroup, imageTypeGroup; + @FXML + protected TextField thresholdInput; + + public RecordImagesInSystemClipboardController() { + targetPathKey = "SnapshotsTargetPath"; + TipsLabelKey = "RecordImagesTips"; + + fileExtensionFilter = CommonValues.ImageExtensionFilter; + } + + @Override + protected void initializeNext() { + try { + recordTypeGroup.selectedToggleProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue ov, + Toggle old_toggle, Toggle new_toggle) { + checkRecordType(); + } + }); + checkRecordType(); + + targetPathInput.textProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue observable, String oldValue, String newValue) { + checkRecordType(); + } + }); + targetPathInput.setText(AppVaribles.getUserConfigPath(targetPathKey).getAbsolutePath()); + + imageTypeGroup.selectedToggleProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue ov, + Toggle old_toggle, Toggle new_toggle) { + checkFormat(); + } + }); + checkFormat(); + + jpegBox.getItems().addAll(Arrays.asList("100", "75", "90", "50", "60", "80", "30", "10")); + jpegBox.valueProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue ov, + String oldValue, String newValue) { + checkJpegQuality(); + } + }); + jpegBox.getSelectionModel().select(0); + checkJpegQuality(); + + thresholdInput.textProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue observable, String oldValue, String newValue) { + checkThreshold(); + } + }); + checkThreshold(); + + } catch (Exception e) { + logger.debug(e.toString()); + } + + } + + private void checkRecordType() { + targetPathInput.setStyle(null); + startButton.setDisable(false); + RadioButton selected = (RadioButton) recordTypeGroup.getSelectedToggle(); + if (AppVaribles.getMessage("View").equals(selected.getText())) { + recordType = RecordType.View; + targetPane.setDisable(true); + openButton.setDisable(true); + + } else { + + if (AppVaribles.getMessage("Save").equals(selected.getText())) { + recordType = RecordType.Save; + } else if (AppVaribles.getMessage("SaveAndView").equals(selected.getText())) { + recordType = RecordType.SaveAndView; + } + + targetPane.setDisable(false); + File file = new File(targetPathInput.getText()); + if (!file.exists() || !file.isDirectory()) { + targetPathInput.setStyle(badStyle); + openButton.setDisable(true); + startButton.setDisable(true); + } else { + AppVaribles.setUserConfigValue(targetPathKey, file.getPath()); + targetPath = file; + openButton.setDisable(false); + } + } + } + + private void checkFormat() { + jpegBox.setDisable(true); + jpegBox.setStyle(null); + thresholdInput.setDisable(true); + + RadioButton selected = (RadioButton) imageTypeGroup.getSelectedToggle(); + if (AppVaribles.getMessage("PNG").equals(selected.getText())) { + imageType = ImageType.PNG; + } else if (AppVaribles.getMessage("CCITT4").equals(selected.getText())) { + imageType = ImageType.TIFF; + thresholdInput.setDisable(false); + } else if (AppVaribles.getMessage("JpegQuailty").equals(selected.getText())) { + imageType = ImageType.JPG; + jpegBox.setDisable(false); + checkJpegQuality(); + } + } + + private void checkJpegQuality() { + jpegQuality = 100; + try { + jpegQuality = Integer.valueOf(jpegBox.getSelectionModel().getSelectedItem()); + if (jpegQuality >= 0 && jpegQuality <= 100) { + jpegBox.setStyle(null); + } else { + jpegBox.setStyle(badStyle); + } + } catch (Exception e) { + jpegBox.setStyle(badStyle); + } + } + + private void checkThreshold() { + try { + if (thresholdInput.getText().isEmpty()) { + threshold = -1; + thresholdInput.setStyle(null); + return; + } + threshold = Integer.valueOf(thresholdInput.getText()); + if (threshold >= 0 && threshold <= 255) { + thresholdInput.setStyle(null); + } else { + threshold = -1; + thresholdInput.setStyle(badStyle); + } + } catch (Exception e) { + threshold = -1; + thresholdInput.setStyle(badStyle); + } + } + + @FXML + @Override + protected void selectTargetPath(ActionEvent event) { + if (targetPathInput == null) { + return; + } + try { + DirectoryChooser chooser = new DirectoryChooser(); + File path = AppVaribles.getUserConfigPath(targetPathKey); + if (path != null) { + chooser.setInitialDirectory(path); + } + File directory = chooser.showDialog(getMyStage()); + if (directory == null) { + return; + } + targetPathInput.setText(directory.getAbsolutePath()); + } catch (Exception e) { + logger.error(e.toString()); + } + } + + @FXML + protected void openTargetPath(ActionEvent event) { + FxmlStage.openTarget(getClass(), null, new File(targetPathInput.getText()).getAbsolutePath()); + } + + @FXML + @Override + public void startAction() { + try { + isHandling = false; + if (AppVaribles.getMessage("StartRecording").equals(startButton.getText())) { + targetPane.setDisable(true); + optionsPane.setDisable(true); + startButton.setText(AppVaribles.getMessage("StopRecording")); + getMyStage().setIconified(true); + recordedNumber = 0; + recordLabel.setText(MessageFormat.format(AppVaribles.getMessage("RecordingImages"), 0)); + final boolean saveImages + = (recordType == RecordType.Save || recordType == RecordType.SaveAndView); + final boolean viewImages + = (recordType == RecordType.View || recordType == RecordType.SaveAndView); + if (targetPath != null) { + if (targetPrefixInput.getText().trim().isEmpty()) { + filePrefix = targetPath.getAbsolutePath() + File.separator; + } else { + filePrefix = targetPath.getAbsolutePath() + File.separator + + targetPrefixInput.getText().trim() + "-"; + } + } + timer = new Timer(); + timer.schedule(new TimerTask() { + @Override + public void run() { + if (isHandling) { + return; + } + Platform.runLater(new Runnable() { + @Override + public void run() { + final Image image = SystemTools.fetchImageInClipboard(false); + if (image == null) { + return; + } + isHandling = true; + if (lastImage != null && ImageTools.isImageSame(lastImage, image)) { + isHandling = false; + return; + } + lastImage = image; + isHandling = false; + if (saveImages) { + saveImage(image); + } + recordedNumber++; + recordLabel.setText(MessageFormat.format(AppVaribles.getMessage("RecordingImages"), recordedNumber)); + if (viewImages) { + ImageViewerController controller = FxmlStage.openImageViewer(getClass(), null); + controller.loadImage(image); + controller.getMyStage().setMaximized(true); + } + } + }); + + } + }, 0, 2000); + } else { + targetPane.setDisable(false); + optionsPane.setDisable(false); + startButton.setText(AppVaribles.getMessage("StartRecording")); + recordLabel.setText(""); + if (timer != null) { + timer.cancel(); + timer = null; + } + } + + } catch (Exception e) { + logger.debug(e.toString()); + } + + } + + private void saveImage(Image image) { + BufferedImage bufferedImage = ImageTools.getBufferedImage(image); + ImageAttributes attributes = new ImageAttributes(); + switch (imageType) { + case TIFF: + ImageBinary imageBinary = new ImageBinary(bufferedImage, threshold); + bufferedImage = imageBinary.operate(); + attributes.setImageFormat("tif"); + attributes.setCompressionType("CCITT T.6"); + break; + case JPG: + bufferedImage = ImageConvert.clearAlpha(bufferedImage); + attributes.setImageFormat("jpg"); + attributes.setCompressionType("JPEG"); + attributes.setQuality(jpegQuality); + break; + case PNG: + default: + attributes.setImageFormat("png"); + break; + + } + File file = new File(filePrefix + DateTools.nowString3() + "-" + + ValueTools.getRandomInt(1000) + "." + attributes.getImageFormat()); + while (file.exists()) { + file = new File(filePrefix + DateTools.nowString3() + "-" + + ValueTools.getRandomInt(1000) + "." + attributes.getImageFormat()); + } + ImageFileWriters.writeImageFile(bufferedImage, attributes, file.getAbsolutePath()); + } + +} diff --git a/MyBox/src/main/java/mara/mybox/controller/SettingsController.java b/MyBox/src/main/java/mara/mybox/controller/SettingsController.java index bd19460fc..521a7e57e 100644 --- a/MyBox/src/main/java/mara/mybox/controller/SettingsController.java +++ b/MyBox/src/main/java/mara/mybox/controller/SettingsController.java @@ -18,17 +18,18 @@ import javafx.scene.control.ToggleGroup; import javafx.scene.control.Tooltip; import javafx.scene.layout.HBox; +import javafx.scene.layout.Region; import javafx.scene.text.Font; import javafx.stage.DirectoryChooser; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.logger; import mara.mybox.db.TableImageHistory; import mara.mybox.db.TableImageInit; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.CommonValues; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.value.CommonValues; import mara.mybox.fxml.FxmlTools; import static mara.mybox.fxml.FxmlTools.badStyle; -import static mara.mybox.objects.AppVaribles.getUserConfigValue; +import static mara.mybox.value.AppVaribles.getUserConfigValue; /** * @Author Mara @@ -38,8 +39,6 @@ */ public class SettingsController extends BaseController { - final protected String TempDirKey; - @FXML private ToggleGroup langGroup, alphaGroup, pdfMemGroup, hisGroup; @FXML @@ -51,14 +50,13 @@ public class SettingsController extends BaseController { @FXML private TextField hisMaxInput, tempDirInput; @FXML - protected ComboBox styleBox, imageWidthBox; + protected ComboBox styleBox, imageWidthBox, fontSizeBox; @FXML protected Button hisClearButton, hisOkButton; @FXML protected HBox pdfMemBox, imageHisBox; public SettingsController() { - TempDirKey = "TempDir"; } @Override @@ -73,6 +71,22 @@ public void changed(ObservableValue ov, } }); + fontSizeBox.getItems().addAll(Arrays.asList( + "9", "10", "12", "14", "15", "16", "17", "18", "19", "20", "21", "22")); + fontSizeBox.getSelectionModel().selectedItemProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue observable, String oldValue, String newValue) { + if (newValue != null && !newValue.isEmpty()) { + try { + int v = Integer.valueOf(newValue); + setPaneFontSize(v); + } catch (Exception e) { + } + } + } + }); + fontSizeBox.getSelectionModel().select(AppVaribles.getPaneFontSize() + ""); + stopAlarmCheck.selectedProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue ov, Boolean old_val, Boolean new_val) { @@ -113,13 +127,13 @@ public void changed(ObservableValue observable, String oldValu return; } tempDirInput.setStyle(null); - AppVaribles.setUserConfigValue(TempDirKey, file.getAbsolutePath()); + AppVaribles.setUserConfigValue(CommonValues.userTempPathKey, file.getAbsolutePath()); } catch (Exception e) { } } }); - tempDirInput.setText(AppVaribles.getUserConfigValue(TempDirKey, CommonValues.UserFilePath)); + tempDirInput.setText(AppVaribles.getUserConfigPath(CommonValues.userTempPathKey).getAbsolutePath()); styleBox.getItems().addAll(Arrays.asList( getMessage("DefaultStyle"), getMessage("caspianStyle"), @@ -385,6 +399,7 @@ protected void clearHistories(ActionEvent event) { Alert alert = new Alert(Alert.AlertType.CONFIRMATION); alert.setTitle(getBaseTitle()); alert.setContentText(AppVaribles.getMessage("SureClear")); + alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); Optional result = alert.showAndWait(); if (result.get() != ButtonType.OK) { return; @@ -451,14 +466,20 @@ protected void noHisAction(ActionEvent event) { protected void selectTemp(ActionEvent event) { try { DirectoryChooser chooser = new DirectoryChooser(); - File path = new File(AppVaribles.getUserConfigPath(TempDirKey, CommonValues.UserFilePath)); - chooser.setInitialDirectory(path); + File path = AppVaribles.getUserTempPath(); + if (path != null) { + chooser.setInitialDirectory(path); + } File directory = chooser.showDialog(getMyStage()); if (directory == null) { return; } + if (CommonValues.AppDataPaths.contains(directory)) { + alertError(AppVaribles.getMessage("DirectoryReserved")); + return; + } AppVaribles.setUserConfigValue(LastPathKey, directory.getPath()); - AppVaribles.setUserConfigValue(TempDirKey, directory.getPath()); + AppVaribles.setUserConfigValue(CommonValues.userTempPathKey, directory.getPath()); tempDirInput.setText(directory.getPath()); } catch (Exception e) { @@ -481,7 +502,7 @@ protected void clearSettings(ActionEvent event) { f = CommonValues.ImageManufactureFileFxml; } reloadStage(f, getMyStage().getTitle()); - popInformation(AppVaribles.getMessage("Successful")); +// popInformation(AppVaribles.getMessage("Successful")); } @FXML diff --git a/MyBox/src/main/java/mara/mybox/controller/SnapScreenController.java b/MyBox/src/main/java/mara/mybox/controller/SnapScreenController.java deleted file mode 100644 index fc2afc915..000000000 --- a/MyBox/src/main/java/mara/mybox/controller/SnapScreenController.java +++ /dev/null @@ -1,749 +0,0 @@ -package mara.mybox.controller; - -import java.io.File; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import javafx.application.Platform; -import javafx.beans.binding.Bindings; -import javafx.beans.value.ChangeListener; -import javafx.beans.value.ObservableValue; -import javafx.concurrent.Task; -import javafx.event.ActionEvent; -import javafx.event.EventHandler; -import javafx.fxml.FXML; -import javafx.scene.control.Button; -import javafx.scene.control.CheckBox; -import javafx.scene.control.RadioButton; -import javafx.scene.control.TextArea; -import javafx.scene.control.TextField; -import javafx.scene.control.Toggle; -import javafx.scene.control.ToggleGroup; -import javafx.scene.layout.VBox; -import javafx.stage.DirectoryChooser; -import javafx.stage.FileChooser; -import mara.mybox.fxml.FxmlTools; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.FileSynchronizeAttributes; -import mara.mybox.tools.DateTools; -import mara.mybox.tools.FileTools; -import static mara.mybox.fxml.FxmlTools.badStyle; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.tools.ValueTools; - -/** - * @Author Mara - * @CreateDate 2019-1-22 - * @Description - * @License Apache License Version 2.0 - */ -public class SnapScreenController extends BaseController { - - protected String lastFileName; - protected Date startTime; - private boolean startHandle, isCopy, byModifyTime; - private int dirType, replaceType; - protected File sourcePath; - protected String renameAppdex = "-m"; - protected StringBuffer newLogs; - protected int newlines, maxLines, totalLines, cacheLines = 200; - protected String strFailedCopy, strCreatedSuccessfully, strCopySuccessfully, strDeleteSuccessfully, strFailedDelete; - protected FileSynchronizeAttributes copyAttr; - private final String FileArrangeSubdirKey, FileArrangeCopyKey, FileArrangeExistedKey, FileArrangeModifyTimeKey, FileArrangeCategoryKey; - - private class DirType { - - private static final int Year = 0; - private static final int Month = 1; - private static final int Day = 2; - } - - private class ReplaceType { - - private static final int ReplaceModified = 0; - private static final int Replace = 1; - private static final int NotCopy = 2; - private static final int Rename = 3; - } - - @FXML - private ToggleGroup filesGroup, byGroup, dirGroup, replaceGroup; - @FXML - protected TextField sourcePathInput, maxLinesinput; - @FXML - protected VBox dirsBox, conditionsBox, logsBox; - @FXML - protected TextArea logsTextArea; - @FXML - protected Button clearButton; - @FXML - private RadioButton copyRadio, moveRadio, replaceModifiedRadio, replaceRadio, renameRadio, notCopyRadio; - @FXML - private RadioButton modifiyTimeRadio, createTimeRadio, monthRadio, dayRadio, yearRadio; - @FXML - private CheckBox verboseCheck; - - public SnapScreenController() { - targetPathKey = "FilesArrageTargetPath"; - sourcePathKey = "FilesArrageSourcePath"; - FileArrangeSubdirKey = "FileArrangeSubdirKey"; - FileArrangeCopyKey = "FileArrangeCopyKey"; - FileArrangeExistedKey = "FileArrangeExistedKey"; - FileArrangeModifyTimeKey = "FileArrangeModifyTimeKey"; - FileArrangeCategoryKey = "FileArrangeCategoryKey"; - - fileExtensionFilter = new ArrayList(); - fileExtensionFilter.add(new FileChooser.ExtensionFilter("*", "*.*")); - } - - @Override - protected void initializeNext() { - try { - initDirTab(); - initConditionTab(); - - operationBarController.startButton.disableProperty().bind( - Bindings.isEmpty(sourcePathInput.textProperty()) - .or(Bindings.isEmpty(targetPathInput.textProperty())) - .or(sourcePathInput.styleProperty().isEqualTo(badStyle)) - .or(targetPathInput.styleProperty().isEqualTo(badStyle)) - ); - - operationBarController.openTargetButton.disableProperty().bind( - operationBarController.startButton.disableProperty() - ); - - } catch (Exception e) { - logger.debug(e.toString()); - } - - } - - private void initDirTab() { - sourcePathInput.setText(AppVaribles.getUserConfigValue(sourcePathKey, CommonValues.UserFilePath)); - sourcePathInput.textProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue observable, - String oldValue, String newValue) { - final File file = new File(newValue); - if (!file.exists() || !file.isDirectory()) { - sourcePathInput.setStyle(badStyle); - return; - } - sourcePathInput.setStyle(null); - AppVaribles.setUserConfigValue(LastPathKey, newValue); - AppVaribles.setUserConfigValue(sourcePathKey, newValue); - } - }); - - targetPathInput.setText(AppVaribles.getUserConfigValue(targetPathKey, CommonValues.UserFilePath)); - targetPathInput.textProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue observable, - String oldValue, String newValue) { - final File file = new File(newValue); - if (!file.isDirectory()) { - targetPathInput.setStyle(badStyle); - return; - } - targetPathInput.setStyle(null); - AppVaribles.setUserConfigValue(LastPathKey, newValue); - AppVaribles.setUserConfigValue(targetPathKey, newValue); - } - }); - - } - - private void initConditionTab() { - - subdirCheck.selectedProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue ov, - Boolean old_toggle, Boolean new_toggle) { - AppVaribles.setUserConfigValue(FileArrangeSubdirKey, isCopy); - } - }); - subdirCheck.setSelected(AppVaribles.getUserConfigBoolean(FileArrangeSubdirKey, true)); - - filesGroup.selectedToggleProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue ov, - Toggle old_toggle, Toggle new_toggle) { - RadioButton selected = (RadioButton) filesGroup.getSelectedToggle(); - isCopy = getMessage("Copy").equals(selected.getText()); - AppVaribles.setUserConfigValue(FileArrangeCopyKey, isCopy); - } - }); - if (AppVaribles.getUserConfigBoolean(FileArrangeCopyKey, true)) { - copyRadio.setSelected(true); - isCopy = true; - } else { - moveRadio.setSelected(true); - isCopy = false; - } - - replaceGroup.selectedToggleProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue ov, - Toggle old_toggle, Toggle new_toggle) { - checkReplaceType(); - } - }); - String replaceSelect = AppVaribles.getUserConfigValue(FileArrangeExistedKey, "ReplaceModified"); - switch (replaceSelect) { - case "ReplaceModified": - replaceModifiedRadio.setSelected(true); - break; - case "Replace": - replaceRadio.setSelected(true); - break; - case "Rename": - renameRadio.setSelected(true); - break; - case "NotCopy": - notCopyRadio.setSelected(true); - break; - } - checkReplaceType(); - - byGroup.selectedToggleProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue ov, - Toggle old_toggle, Toggle new_toggle) { - RadioButton selected = (RadioButton) byGroup.getSelectedToggle(); - byModifyTime = getMessage("ModifyTime").equals(selected.getText()); - AppVaribles.setUserConfigValue(FileArrangeModifyTimeKey, byModifyTime); - } - }); - if (AppVaribles.getUserConfigBoolean(FileArrangeModifyTimeKey, true)) { - modifiyTimeRadio.setSelected(true); - byModifyTime = true; - } else { - createTimeRadio.setSelected(true); - byModifyTime = false; - } - - dirGroup.selectedToggleProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue ov, - Toggle old_toggle, Toggle new_toggle) { - checkDirType(); - } - }); - String dirSelect = AppVaribles.getUserConfigValue(FileArrangeCategoryKey, "Month"); - switch (dirSelect) { - case "Year": - yearRadio.setSelected(true); - break; - case "Month": - monthRadio.setSelected(true); - break; - case "Day": - dayRadio.setSelected(true); - break; - } - checkDirType(); - - } - - private void checkReplaceType() { - RadioButton selected = (RadioButton) replaceGroup.getSelectedToggle(); - if (getMessage("ReplaceModified").equals(selected.getText())) { - replaceType = ReplaceType.ReplaceModified; - AppVaribles.setUserConfigValue(FileArrangeExistedKey, "ReplaceModified"); - } else if (getMessage("NotCopy").equals(selected.getText())) { - replaceType = ReplaceType.NotCopy; - AppVaribles.setUserConfigValue(FileArrangeExistedKey, "NotCopy"); - } else if (getMessage("Replace").equals(selected.getText())) { - replaceType = ReplaceType.Replace; - AppVaribles.setUserConfigValue(FileArrangeExistedKey, "Replace"); - } else if (getMessage("Rename").equals(selected.getText())) { - replaceType = ReplaceType.Rename; - AppVaribles.setUserConfigValue(FileArrangeExistedKey, "Rename"); - } else { - replaceType = ReplaceType.ReplaceModified; - AppVaribles.setUserConfigValue(FileArrangeExistedKey, "ReplaceModified"); - } - - } - - private void checkDirType() { - RadioButton selected = (RadioButton) dirGroup.getSelectedToggle(); - if (getMessage("Year").equals(selected.getText())) { - dirType = DirType.Year; - AppVaribles.setUserConfigValue(FileArrangeCategoryKey, "Year"); - } else if (getMessage("Month").equals(selected.getText())) { - dirType = DirType.Month; - AppVaribles.setUserConfigValue(FileArrangeCategoryKey, "Month"); - } else if (getMessage("Day").equals(selected.getText())) { - dirType = DirType.Day; - AppVaribles.setUserConfigValue(FileArrangeCategoryKey, "Day"); - } else { - dirType = DirType.Month; - AppVaribles.setUserConfigValue(FileArrangeCategoryKey, "Month"); - } - } - - @FXML - protected void selectSourcePath(ActionEvent event) { - try { - DirectoryChooser chooser = new DirectoryChooser(); - File path = new File(AppVaribles.getUserConfigPath(sourcePathKey, CommonValues.UserFilePath)); - chooser.setInitialDirectory(path); - File directory = chooser.showDialog(getMyStage()); - if (directory == null) { - return; - } - sourcePathInput.setText(directory.getPath()); - } catch (Exception e) { - logger.error(e.toString()); - } - } - - @FXML - @Override - protected void selectTargetPath(ActionEvent event) { - if (targetPathInput == null) { - return; - } - try { - DirectoryChooser chooser = new DirectoryChooser(); - File path = new File(AppVaribles.getUserConfigPath(targetPathKey, CommonValues.UserFilePath)); - chooser.setInitialDirectory(path); - File directory = chooser.showDialog(getMyStage()); - if (directory == null) { - return; - } - targetPathInput.setText(directory.getPath()); - } catch (Exception e) { - logger.error(e.toString()); - } - } - - @FXML - @Override - protected void openTarget(ActionEvent event) { - OpenFile.openTarget(getClass(), null, new File(targetPathInput.getText()).getAbsolutePath()); - } - - protected boolean initAttributes() { - try { - sourcePath = new File(sourcePathInput.getText()); - if (!paused || lastFileName == null) { - copyAttr = new FileSynchronizeAttributes(); - - logsTextArea.setText(AppVaribles.getMessage("SourcePath") + ": " + sourcePathInput.getText() + "\n"); - logsTextArea.appendText(AppVaribles.getMessage("TargetPath") + ": " + targetPathInput.getText() + "\n"); - newLogs = new StringBuffer(); - newlines = 0; - totalLines = 0; - - try { - maxLines = Integer.parseInt(maxLinesinput.getText()); - } catch (Exception e) { - maxLines = 5000; - } - - strFailedCopy = AppVaribles.getMessage("FailedCopy") + ": "; - strCreatedSuccessfully = AppVaribles.getMessage("CreatedSuccessfully") + ": "; - strCopySuccessfully = AppVaribles.getMessage("CopySuccessfully") + ": "; - strDeleteSuccessfully = AppVaribles.getMessage("DeletedSuccessfully") + ": "; - strFailedDelete = AppVaribles.getMessage("FailedDelete") + ": "; - - targetPath = new File(targetPathInput.getText()); - if (!targetPath.exists()) { - targetPath.mkdirs(); - updateLogs(strCreatedSuccessfully + targetPath.getAbsolutePath(), true); - } - targetPath.setWritable(true); - targetPath.setExecutable(true); - - startHandle = true; - lastFileName = null; - - } else { - startHandle = false; - updateLogs(getMessage("LastHanldedFile") + " " + lastFileName, true); - } - - paused = false; - startTime = new Date(); - - return true; - - } catch (Exception e) { - logger.error(e.toString()); - return false; - } - } - - @FXML - @Override - protected void startProcess(ActionEvent event) { - try { - if (!initAttributes()) { - return; - } - - updateInterface("Started"); - task = new Task() { - - @Override - protected Void call() { - arranegFiles(sourcePath); - return null; - } - - @Override - protected void succeeded() { - super.succeeded(); - updateInterface("Done"); - } - - @Override - protected void cancelled() { - super.cancelled(); - updateInterface("Canceled"); - } - - @Override - protected void failed() { - super.failed(); - updateInterface("Failed"); - } - }; - Thread thread = new Thread(task); - thread.setDaemon(true); - thread.start(); - - } catch (Exception e) { - updateInterface("Failed"); - logger.error(e.toString()); - } - - } - - @Override - protected void updateInterface(final String newStatus) { - currentStatus = newStatus; - Platform.runLater(new Runnable() { - @Override - public void run() { - try { - if (paused) { - updateLogs(AppVaribles.getMessage("Paused"), true); - } else { - updateLogs(AppVaribles.getMessage(newStatus), true); - } - switch (newStatus) { - case "Started": - operationBarController.statusLabel.setText(getMessage("Handling...") + " " - + getMessage("StartTime") - + ": " + DateTools.datetimeToString(startTime)); - operationBarController.startButton.setText(AppVaribles.getMessage("Cancel")); - operationBarController.startButton.setOnAction(new EventHandler() { - @Override - public void handle(ActionEvent event) { - cancelProcess(event); - } - }); - operationBarController.pauseButton.setVisible(true); - operationBarController.pauseButton.setDisable(false); - operationBarController.pauseButton.setText(AppVaribles.getMessage("Pause")); - operationBarController.pauseButton.setOnAction(new EventHandler() { - @Override - public void handle(ActionEvent event) { - pauseProcess(event); - } - }); - operationBarController.progressBar.setProgress(-1); - dirsBox.setDisable(true); - conditionsBox.setDisable(true); - break; - - case "Done": - default: - - if (paused) { - operationBarController.startButton.setText(AppVaribles.getMessage("Cancel")); - operationBarController.startButton.setOnAction(new EventHandler() { - @Override - public void handle(ActionEvent event) { - cancelProcess(event); - } - }); - operationBarController.pauseButton.setVisible(true); - operationBarController.pauseButton.setDisable(false); - operationBarController.pauseButton.setText(AppVaribles.getMessage("Continue")); - operationBarController.pauseButton.setOnAction(new EventHandler() { - @Override - public void handle(ActionEvent event) { - startProcess(event); - } - }); - - } else { - operationBarController.startButton.setText(AppVaribles.getMessage("Start")); - operationBarController.startButton.setOnAction(new EventHandler() { - @Override - public void handle(ActionEvent event) { - startProcess(event); - } - }); - operationBarController.pauseButton.setVisible(false); - operationBarController.pauseButton.setDisable(true); - operationBarController.progressBar.setProgress(1); - dirsBox.setDisable(false); - conditionsBox.setDisable(false); - } - - showCost(); - updateLogs(getMessage("StartTime") + ": " + DateTools.datetimeToString(startTime) + " " - + AppVaribles.getMessage("Cost") + ": " + DateTools.showTime(new Date().getTime() - startTime.getTime()), false, true); - updateLogs(AppVaribles.getMessage("TotalCheckedFiles") + ": " + copyAttr.getTotalFilesNumber() + " " - + AppVaribles.getMessage("TotalCheckedDirectories") + ": " + copyAttr.getTotalDirectoriesNumber() + " " - + AppVaribles.getMessage("TotalCheckedSize") + ": " + FileTools.showFileSize(copyAttr.getTotalSize()), false, true); - updateLogs(AppVaribles.getMessage("TotalCopiedFiles") + ": " + copyAttr.getCopiedFilesNumber() + " " - + AppVaribles.getMessage("TotalCopiedDirectories") + ": " + copyAttr.getCopiedDirectoriesNumber() + " " - + AppVaribles.getMessage("TotalCopiedSize") + ": " + FileTools.showFileSize(copyAttr.getCopiedSize()), false, true); - if (!isCopy) { - updateLogs(AppVaribles.getMessage("TotalDeletedFiles") + ": " + copyAttr.getDeletedFiles() + " " - + AppVaribles.getMessage("TotalDeletedDirectories") + ": " + copyAttr.getDeletedDirectories() + " " - + AppVaribles.getMessage("TotalDeletedSize") + ": " + FileTools.showFileSize(copyAttr.getDeletedSize()), false, true); - } - - if (operationBarController.miaoCheck.isSelected()) { - FxmlTools.miao3(); - } - } - - } catch (Exception e) { - logger.error(e.toString()); - } - } - }); - - } - - protected void showCost() { - if (operationBarController.statusLabel == null) { - return; - } - long cost = (new Date().getTime() - startTime.getTime()) / 1000; - double avg = 0; - if (copyAttr.getCopiedFilesNumber() != 0) { - avg = ValueTools.roundDouble3((double) cost / copyAttr.getCopiedFilesNumber()); - } - String s; - if (paused) { - s = getMessage("Paused"); - } else { - s = getMessage(currentStatus); - } - s += ". " + getMessage("HandledThisTime") + ": " + copyAttr.getCopiedFilesNumber() + " " - + getMessage("Cost") + ": " + cost + " " + getMessage("Seconds") + ". " - + getMessage("Average") + ": " + avg + " " + getMessage("SecondsPerItem") + ". " - + getMessage("StartTime") + ": " + DateTools.datetimeToString(startTime) + ", " - + getMessage("EndTime") + ": " + DateTools.datetimeToString(new Date()); - operationBarController.statusLabel.setText(s); - } - - protected boolean arranegFiles(File sourcePath) { - try { - if (sourcePath == null || !sourcePath.exists() || !sourcePath.isDirectory()) { - return false; - } - File[] files = sourcePath.listFiles(); - String srcFileName; - long len; - for (File srcFile : files) { - if (task.isCancelled()) { - return false; - } - srcFileName = srcFile.getAbsolutePath(); - logger.debug(srcFileName); - len = srcFile.length(); - if (!startHandle) { - if (lastFileName.equals(srcFileName)) { - startHandle = true; - updateLogs(getMessage("ReachFile") + " " + lastFileName, true); - } - if (srcFile.isFile()) { - continue; - } - } else { - if (srcFile.isFile()) { - copyAttr.setTotalFilesNumber(copyAttr.getTotalFilesNumber() + 1); - } else { - copyAttr.setTotalDirectoriesNumber(copyAttr.getTotalDirectoriesNumber() + 1); - } - copyAttr.setTotalSize(copyAttr.getTotalSize() + srcFile.length()); - } - if (srcFile.isDirectory()) { - if (subdirCheck.isSelected()) { - if (verboseCheck.isSelected()) { - updateLogs(getMessage("HandlingDirectory") + " " + srcFileName, true); - } - arranegFiles(srcFile); - } - continue; - } else if (!startHandle) { - continue; - } - try { - Calendar c = Calendar.getInstance(); - if (byModifyTime) { - c.setTimeInMillis(srcFile.lastModified()); - } else { - c.setTimeInMillis(FileTools.getFileCreateTime(srcFileName)); - } - File path; - String month, day; - if (c.get(Calendar.MONTH) > 8) { - month = (c.get(Calendar.MONTH) + 1) + ""; - } else { - month = "0" + (c.get(Calendar.MONTH) + 1); - } - if (c.get(Calendar.DAY_OF_MONTH) > 9) { - day = c.get(Calendar.DAY_OF_MONTH) + ""; - } else { - day = "0" + c.get(Calendar.DAY_OF_MONTH); - } - switch (dirType) { - case DirType.Year: - path = new File(targetPath + File.separator + c.get(Calendar.YEAR)); - if (!path.exists()) { - path.mkdirs(); - if (verboseCheck.isSelected()) { - updateLogs(strCreatedSuccessfully + path.getAbsolutePath()); - } - } - break; - case DirType.Day: - path = new File(targetPath + File.separator + c.get(Calendar.YEAR) - + File.separator + c.get(Calendar.YEAR) + "-" + month - + File.separator + c.get(Calendar.YEAR) + "-" + month + "-" + day); - if (!path.exists()) { - path.mkdirs(); - if (verboseCheck.isSelected()) { - updateLogs(strCreatedSuccessfully + path.getAbsolutePath()); - } - } - break; - case DirType.Month: - default: - path = new File(targetPath + File.separator + c.get(Calendar.YEAR) - + File.separator + c.get(Calendar.YEAR) + "-" + month); - if (!path.exists()) { - path.mkdirs(); - if (verboseCheck.isSelected()) { - updateLogs(strCreatedSuccessfully + path.getAbsolutePath()); - } - } - break; - } - File newFile = new File(path.getAbsolutePath() + File.separator + srcFile.getName()); - if (newFile.exists()) { - switch (replaceType) { - case ReplaceType.NotCopy: - continue; - case ReplaceType.Rename: - newFile = renameExistedFile(newFile); - break; - case ReplaceType.Replace: - break; - case ReplaceType.ReplaceModified: - if (srcFile.lastModified() <= newFile.lastModified()) { - continue; - } - } - } - Files.copy(Paths.get(srcFileName), Paths.get(newFile.getAbsolutePath()), - StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES); - - if (!isCopy) { - srcFile.delete(); - copyAttr.setDeletedSize(copyAttr.getDeletedSize() + len); - if (verboseCheck.isSelected()) { - updateLogs(strDeleteSuccessfully + srcFileName); - } - } - copyAttr.setCopiedFilesNumber(copyAttr.getCopiedFilesNumber() + 1); - copyAttr.setCopiedSize(copyAttr.getCopiedSize() + len); - if (verboseCheck.isSelected()) { - updateLogs(copyAttr.getCopiedFilesNumber() + " " + strCopySuccessfully - + srcFileName + " -> " + newFile.getAbsolutePath()); - } - lastFileName = srcFileName; - - } catch (Exception e) { - updateLogs(strFailedCopy + srcFileName + "\n" + e.toString()); - } - - } - - return true; - } catch (Exception e) { - logger.error(e.toString()); - return false; - } - - } - - private File renameExistedFile(File file) { - if (!file.exists()) { - return file; - } - String newName = FileTools.getFilePrefix(file.getName()) + renameAppdex + "." + FileTools.getFileSuffix(file.getName()); - File newFile = new File(file.getParent() + File.separator + newName); - if (!newFile.exists()) { - return newFile; - } - return renameExistedFile(newFile); - } - - protected void updateLogs(final String line) { - updateLogs(line, true, false); - } - - protected void updateLogs(final String line, boolean immediate) { - updateLogs(line, true, immediate); - } - - protected void updateLogs(final String line, boolean showTime, boolean immediate) { - try { - if (showTime) { - newLogs.append(DateTools.datetimeToString(new Date())).append(" "); - } - newLogs.append(line).append("\n"); - long past = new Date().getTime() - startTime.getTime(); - if (immediate || newlines++ > cacheLines || past > 5000) { - Platform.runLater(new Runnable() { - @Override - public void run() { - logsTextArea.appendText(newLogs.toString()); - totalLines += newlines; - if (totalLines > maxLines + cacheLines) { - logsTextArea.deleteText(0, newLogs.length()); - } - newLogs = new StringBuffer(); - newlines = 0; - } - }); - } - } catch (Exception e) { - - } - } - - @FXML - protected void clearLogs(ActionEvent event) { - logsTextArea.setText(""); - } - -} diff --git a/MyBox/src/main/java/mara/mybox/controller/TargetSelectionController.java b/MyBox/src/main/java/mara/mybox/controller/TargetSelectionController.java index e712f3e30..06ed7128e 100644 --- a/MyBox/src/main/java/mara/mybox/controller/TargetSelectionController.java +++ b/MyBox/src/main/java/mara/mybox/controller/TargetSelectionController.java @@ -5,7 +5,7 @@ */ package mara.mybox.controller; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.logger; /** * FXML Controller class diff --git a/MyBox/src/main/java/mara/mybox/controller/TextEditerController.java b/MyBox/src/main/java/mara/mybox/controller/TextEditerController.java index 52d820436..83d3e5b3d 100644 --- a/MyBox/src/main/java/mara/mybox/controller/TextEditerController.java +++ b/MyBox/src/main/java/mara/mybox/controller/TextEditerController.java @@ -10,9 +10,9 @@ import javafx.scene.control.Tooltip; import javafx.scene.text.Font; import mara.mybox.fxml.FxmlTools; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.FileEditInformation; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.data.FileEditInformation; import mara.mybox.tools.ByteTools; import mara.mybox.tools.TextTools; @@ -25,6 +25,8 @@ public class TextEditerController extends FileEditerController { public TextEditerController() { + TipsLabelKey = "TextEditerTips"; + setTextType(); } @@ -74,6 +76,10 @@ public void changed(ObservableValue ov, String oldValue, String newValue) { } } }); + + tips = new Tooltip(AppVaribles.getMessage("BOMcomments")); + tips.setFont(new Font(16)); + FxmlTools.quickTooltip(targetBomCheck, tips); } } diff --git a/MyBox/src/main/java/mara/mybox/controller/TextEncodingBatchController.java b/MyBox/src/main/java/mara/mybox/controller/TextEncodingBatchController.java index 623ff2914..e99d7af61 100644 --- a/MyBox/src/main/java/mara/mybox/controller/TextEncodingBatchController.java +++ b/MyBox/src/main/java/mara/mybox/controller/TextEncodingBatchController.java @@ -14,13 +14,16 @@ import javafx.scene.control.RadioButton; import javafx.scene.control.Toggle; import javafx.scene.control.ToggleGroup; +import javafx.scene.control.Tooltip; +import javafx.scene.text.Font; import javafx.stage.FileChooser; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.FileEditInformation; -import mara.mybox.objects.FileEditInformation.Edit_Type; -import mara.mybox.objects.FileInformation; +import mara.mybox.fxml.FxmlTools; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.getMessage; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.data.FileEditInformation; +import mara.mybox.data.FileEditInformation.Edit_Type; +import mara.mybox.data.FileInformation; import mara.mybox.tools.FileTools; import mara.mybox.tools.TextTools; @@ -99,6 +102,10 @@ public void changed(ObservableValue ov, String oldValue, String newValue) { } }); targetBox.getSelectionModel().select(Charset.defaultCharset().name()); + + Tooltip tips = new Tooltip(AppVaribles.getMessage("BOMcomments")); + tips.setFont(new Font(16)); + FxmlTools.quickTooltip(targetBomCheck, tips); } } diff --git a/MyBox/src/main/java/mara/mybox/controller/TextLineBreakBatchController.java b/MyBox/src/main/java/mara/mybox/controller/TextLineBreakBatchController.java index 761d218cf..8bacdfa66 100644 --- a/MyBox/src/main/java/mara/mybox/controller/TextLineBreakBatchController.java +++ b/MyBox/src/main/java/mara/mybox/controller/TextLineBreakBatchController.java @@ -7,9 +7,9 @@ import javafx.scene.control.RadioButton; import javafx.scene.control.Toggle; import javafx.scene.control.ToggleGroup; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.FileEditInformation.Line_Break; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.AppVaribles; +import mara.mybox.data.FileEditInformation.Line_Break; import mara.mybox.tools.TextTools; /** diff --git a/MyBox/src/main/java/mara/mybox/controller/WebBrowser.java b/MyBox/src/main/java/mara/mybox/controller/WebBrowser.java index 11e2fcce2..f183bed62 100644 --- a/MyBox/src/main/java/mara/mybox/controller/WebBrowser.java +++ b/MyBox/src/main/java/mara/mybox/controller/WebBrowser.java @@ -20,8 +20,8 @@ import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.AppVaribles; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.AppVaribles; import static mara.mybox.fxml.FxmlTools.badStyle; /** @@ -37,7 +37,7 @@ public class WebBrowser implements Initializable { private WebEngine webEngine; private int cols, rows, delay, fontSize, orginalStageHeight, orginalStageY; protected int lastHtmlLen, lastCodesLen, snapHeight, snapCount; - private boolean isSettingValues, isOneImage; + private boolean isOneImage; private URL url; private List images; private File targetFile; @@ -163,13 +163,13 @@ public String getBrowserContents() { // final FileChooser fileChooser = new FileChooser(); // File path; // if (isOneImage) { -// path = new File(AppVaribles.getUserConfigValue(HtmlImagePathKey, CommonValues.UserFilePath)); +// path = new File(AppVaribles.getUserConfigValue(HtmlImagePathKey); // fileChooser.getExtensionFilters().addAll(CommonValues.ImageExtensionFilter); // } else { -// path = new File(AppVaribles.getUserConfigValue(HtmlPdfPathKey, CommonValues.UserFilePath)); +// path = new File(AppVaribles.getUserConfigValue(HtmlPdfPathKey); // fileChooser.getExtensionFilters().addAll(CommonValues.PdfExtensionFilter); // } -// fileChooser.setInitialDirectory(path); +// if ( path.exists() ) fileChooser.setInitialDirectory(path); // final File file = fileChooser.showSaveDialog(getMyStage()); // if (file == null) { // return; diff --git a/MyBox/src/main/java/mara/mybox/controller/WeiboSnapController.java b/MyBox/src/main/java/mara/mybox/controller/WeiboSnapController.java index 72b40c77e..873205089 100644 --- a/MyBox/src/main/java/mara/mybox/controller/WeiboSnapController.java +++ b/MyBox/src/main/java/mara/mybox/controller/WeiboSnapController.java @@ -28,15 +28,15 @@ import javafx.stage.Stage; import javafx.stage.StageStyle; import javafx.stage.WindowEvent; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.getMessage; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.WeiboSnapParameters; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.getMessage; +import mara.mybox.value.CommonValues; +import mara.mybox.data.WeiboSnapParameters; import mara.mybox.tools.DateTools; import mara.mybox.fxml.FxmlTools; import static mara.mybox.fxml.FxmlTools.badStyle; -import static mara.mybox.objects.AppVaribles.getUserConfigValue; +import static mara.mybox.value.AppVaribles.getUserConfigValue; import mara.mybox.tools.PdfTools.PdfImageFormat; /** @@ -68,9 +68,9 @@ public class WeiboSnapController extends BaseController { @FXML private TextField addressInput, pathInput, startInput, endInput; @FXML - private Button startButton, exampleButton; + private Button exampleButton; @FXML - private CheckBox pdfCheck, htmlCheck, pixCheck, keepPageCheck, miaoCheck; + private CheckBox pdfCheck, htmlCheck, pixCheck, keepPageCheck, miaoCheck, ditherCheck; @FXML private CheckBox expandCommentsCheck, expandPicturesCheck, openPathCheck, closeWindowCheck; @FXML @@ -362,6 +362,7 @@ public void changed(ObservableValue observable, String oldValu } }); checkThreshold(); + FxmlTools.setComments(ditherCheck, new Tooltip(getMessage("DitherComments"))); } @@ -369,6 +370,7 @@ private void checkFormat() { jpegBox.setDisable(true); jpegBox.setStyle(null); thresholdInput.setDisable(true); + ditherCheck.setDisable(true); RadioButton selected = (RadioButton) formatGroup.getSelectedToggle(); if (AppVaribles.getMessage("PNG").equals(selected.getText())) { @@ -376,6 +378,7 @@ private void checkFormat() { } else if (AppVaribles.getMessage("CCITT4").equals(selected.getText())) { format = PdfImageFormat.Tiff; thresholdInput.setDisable(false); + ditherCheck.setDisable(false); } else if (AppVaribles.getMessage("JpegQuailty").equals(selected.getText())) { format = PdfImageFormat.Jpeg; jpegBox.setDisable(false); @@ -405,7 +408,7 @@ private void checkThreshold() { return; } threshold = Integer.valueOf(thresholdInput.getText()); - if (threshold >= 0 && threshold <= 100) { + if (threshold >= 0 && threshold <= 255) { thresholdInput.setStyle(null); } else { threshold = -1; @@ -717,7 +720,7 @@ public void changed(ObservableValue observable, String oldValu } } }); - pathInput.setText(AppVaribles.getUserConfigValue(WeiboTargetPathKey, CommonValues.UserFilePath)); + pathInput.setText(AppVaribles.getUserConfigPath(WeiboTargetPathKey).getAbsolutePath()); pdfCheck.selectedProperty().addListener(new ChangeListener() { @Override @@ -868,8 +871,10 @@ protected void pdfMemUnlimit(ActionEvent event) { protected void selectPath(ActionEvent event) { try { DirectoryChooser chooser = new DirectoryChooser(); - File path = new File(AppVaribles.getUserConfigPath(WeiboTargetPathKey, CommonValues.UserFilePath)); - chooser.setInitialDirectory(path); + File path = AppVaribles.getUserConfigPath(WeiboTargetPathKey); + if (path != null) { + chooser.setInitialDirectory(path); + } File directory = chooser.showDialog(getMyStage()); if (directory == null) { return; @@ -884,7 +889,8 @@ protected void selectPath(ActionEvent event) { } @FXML - protected void startAction(ActionEvent event) { + @Override + public void startAction() { makeParameters(); if (parameters == null) { popError(AppVaribles.getMessage("ParametersError")); @@ -967,10 +973,11 @@ private WeiboSnapParameters makeParameters() { parameters.setSavePictures(pixCheck.isSelected()); parameters.setExpandPicture(expandPicturesCheck.isSelected()); parameters.setCategory(categoryType); - parameters.setTempdir(AppVaribles.getTempPathFile()); + parameters.setTempdir(AppVaribles.getUserTempPath()); parameters.setPdfScale(pdfScale); parameters.setOpenPathWhenStop(openPathCheck.isSelected()); parameters.setFontName("幼圆"); + parameters.setDithering(ditherCheck.isSelected()); return parameters; } catch (Exception e) { parameters = null; diff --git a/MyBox/src/main/java/mara/mybox/controller/WeiboSnapRunController.java b/MyBox/src/main/java/mara/mybox/controller/WeiboSnapRunController.java index 5154c59d9..84519a22c 100644 --- a/MyBox/src/main/java/mara/mybox/controller/WeiboSnapRunController.java +++ b/MyBox/src/main/java/mara/mybox/controller/WeiboSnapRunController.java @@ -1,5 +1,6 @@ package mara.mybox.controller; +import mara.mybox.fxml.FxmlStage; import com.sun.management.OperatingSystemMXBean; import java.awt.image.BufferedImage; import java.io.BufferedWriter; @@ -41,15 +42,15 @@ import javafx.stage.Screen; import javafx.stage.Stage; import javafx.stage.StageStyle; -import mara.mybox.imagefile.ImageFileWriters; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.WeiboSnapParameters; +import mara.mybox.image.file.ImageFileWriters; +import mara.mybox.value.AppVaribles; +import mara.mybox.value.CommonValues; +import mara.mybox.data.WeiboSnapParameters; import mara.mybox.tools.DateTools; import mara.mybox.tools.FileTools; -import mara.mybox.fxml.FxmlImageTools; +import mara.mybox.fxml.image.ImageTools; import mara.mybox.fxml.FxmlTools; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.logger; import mara.mybox.tools.NetworkTools; import static mara.mybox.tools.NetworkTools.checkWeiboPassport; import mara.mybox.tools.PdfTools; @@ -388,9 +389,11 @@ public void handle(WebEvent ev) { startTime = new Date().getTime(); tempdir = parameters.getTempdir(); if (tempdir == null || !tempdir.exists() || !tempdir.isDirectory()) { - tempdir = new File(CommonValues.UserFilePath); + tempdir = new File(CommonValues.AppDataRoot); } else if (!tempdir.exists()) { - tempdir.mkdirs(); + if (!tempdir.mkdirs()) { + tempdir = CommonValues.AppTempPath; + } } memSettings = AppVaribles.PdfMemUsage.setTempDir(tempdir); @@ -1195,7 +1198,7 @@ public void run() { if (parameters.isUseTempFiles()) { try { String filename = pdfFilename + "-Image" + imageNumber + ".png"; - bufferedImage = FxmlImageTools.getBufferedImage(snapshot); + bufferedImage = ImageTools.getBufferedImage(snapshot); snapshot = null; ImageFileWriters.writeImageFile(bufferedImage, "png", filename); bufferedImage = null; @@ -1215,7 +1218,7 @@ public void run() { Image lasSnap = images.get(images.size() - 1); int y1 = snapHeight - pageHeight + 100; // logger.debug(pageHeight + " " + snapHeight + " " + screenHeight + " " + y1); - lasSnap = FxmlImageTools.cropImage(lasSnap, 0, y1, + lasSnap = ImageTools.cropImage(lasSnap, 0, y1, (int) lasSnap.getWidth() - 1, (int) lasSnap.getHeight() - 1); images.set(images.size() - 1, lasSnap); } @@ -1251,7 +1254,7 @@ public void run() { if (!snapFailed) { if (!parameters.isImagePerScreen() && !images.isEmpty()) { - Image finalImage = FxmlImageTools.combineSingleColumn(images); + Image finalImage = ImageTools.combineSingleColumn(images); logger.debug("combineSingleColumn"); images = new ArrayList<>(); if (finalImage == null) { @@ -1394,7 +1397,7 @@ public void endSnap() { AppVaribles.setUserConfigValue("WeiBoCurrentPageKey", currentPage + ""); AppVaribles.setUserConfigValue("WeiBoCurrentMonthPageCountKey", currentMonthPageCount + ""); if (parameters.isOpenPathWhenStop()) { - OpenFile.openTarget(getClass(), null, rootPath.getAbsolutePath()); + FxmlStage.openTarget(getClass(), null, rootPath.getAbsolutePath()); } closeStage(); } catch (Exception e) { @@ -1404,9 +1407,6 @@ public void endSnap() { @Override public boolean stageClosing() { - if (!super.stageClosing()) { - return false; - } webEngine.getLoadWorker().cancel(); webEngine = null; if (loadTimer != null) { @@ -1426,11 +1426,12 @@ public boolean stageClosing() { */ Thread thread = Thread.currentThread(); System.gc(); - return true; + + return super.stageClosing(); } public void openPath() { - OpenFile.openTarget(getClass(), null, rootPath.getAbsolutePath()); + FxmlStage.openTarget(getClass(), null, rootPath.getAbsolutePath()); } public WeiboSnapController getParent() { diff --git a/MyBox/src/main/java/mara/mybox/controller/WeiboSnapingInfoController.java b/MyBox/src/main/java/mara/mybox/controller/WeiboSnapingInfoController.java index 3befb6529..7412781ca 100644 --- a/MyBox/src/main/java/mara/mybox/controller/WeiboSnapingInfoController.java +++ b/MyBox/src/main/java/mara/mybox/controller/WeiboSnapingInfoController.java @@ -8,8 +8,8 @@ import javafx.scene.control.ProgressIndicator; import javafx.scene.control.TextArea; import javafx.scene.layout.VBox; -import mara.mybox.objects.CommonValues; -import static mara.mybox.objects.AppVaribles.logger; +import mara.mybox.value.CommonValues; +import static mara.mybox.value.AppVaribles.logger; /** * @Author Mara diff --git a/MyBox/src/main/java/mara/mybox/objects/AlarmClock.java b/MyBox/src/main/java/mara/mybox/data/AlarmClock.java similarity index 98% rename from MyBox/src/main/java/mara/mybox/objects/AlarmClock.java rename to MyBox/src/main/java/mara/mybox/data/AlarmClock.java index dabed329e..5b7176a67 100644 --- a/MyBox/src/main/java/mara/mybox/objects/AlarmClock.java +++ b/MyBox/src/main/java/mara/mybox/data/AlarmClock.java @@ -1,5 +1,7 @@ -package mara.mybox.objects; +package mara.mybox.data; +import mara.mybox.value.AppVaribles; +import mara.mybox.value.CommonValues; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.InputStream; @@ -15,10 +17,10 @@ import javafx.collections.FXCollections; import javafx.collections.ObservableList; import mara.mybox.db.TableAlarmClock; -import static mara.mybox.objects.AppVaribles.executorService; -import static mara.mybox.objects.AppVaribles.scheduledTasks; +import static mara.mybox.value.AppVaribles.executorService; +import static mara.mybox.value.AppVaribles.scheduledTasks; import mara.mybox.tools.DateTools; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.logger; /** diff --git a/MyBox/src/main/java/mara/mybox/objects/AlarmClockTask.java b/MyBox/src/main/java/mara/mybox/data/AlarmClockTask.java similarity index 95% rename from MyBox/src/main/java/mara/mybox/objects/AlarmClockTask.java rename to MyBox/src/main/java/mara/mybox/data/AlarmClockTask.java index 16452cbb1..4b07a1596 100644 --- a/MyBox/src/main/java/mara/mybox/objects/AlarmClockTask.java +++ b/MyBox/src/main/java/mara/mybox/data/AlarmClockTask.java @@ -1,5 +1,7 @@ -package mara.mybox.objects; +package mara.mybox.data; +import mara.mybox.value.AppVaribles; +import mara.mybox.value.CommonValues; import java.util.Date; import java.util.TimerTask; import java.util.concurrent.ScheduledFuture; @@ -13,9 +15,9 @@ import javafx.stage.Stage; import javafx.stage.WindowEvent; import mara.mybox.controller.AlarmClockRunController; -import mara.mybox.objects.AlarmClock.AlarmType; -import static mara.mybox.objects.AppVaribles.logger; -import static mara.mybox.objects.AppVaribles.scheduledTasks; +import mara.mybox.data.AlarmClock.AlarmType; +import static mara.mybox.value.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.scheduledTasks; import mara.mybox.tools.DateTools; /** diff --git a/MyBox/src/main/java/mara/mybox/objects/BytesEditInformation.java b/MyBox/src/main/java/mara/mybox/data/BytesEditInformation.java similarity index 99% rename from MyBox/src/main/java/mara/mybox/objects/BytesEditInformation.java rename to MyBox/src/main/java/mara/mybox/data/BytesEditInformation.java index b863e9c2f..a5b9a90b1 100644 --- a/MyBox/src/main/java/mara/mybox/objects/BytesEditInformation.java +++ b/MyBox/src/main/java/mara/mybox/data/BytesEditInformation.java @@ -1,10 +1,10 @@ -package mara.mybox.objects; +package mara.mybox.data; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.OutputStreamWriter; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.logger; import mara.mybox.tools.ByteTools; import mara.mybox.tools.FileTools; import mara.mybox.tools.TextTools; diff --git a/MyBox/src/main/java/mara/mybox/data/ColorStatistic.java b/MyBox/src/main/java/mara/mybox/data/ColorStatistic.java new file mode 100644 index 000000000..ff924b637 --- /dev/null +++ b/MyBox/src/main/java/mara/mybox/data/ColorStatistic.java @@ -0,0 +1,130 @@ +package mara.mybox.data; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javafx.scene.paint.Color; +import mara.mybox.tools.ValueTools; + +/** + * @Author Mara + * @CreateDate 2019-2-11 12:53:19 + * @Version 1.0 + * @Description + * @License Apache License Version 2.0 + */ +public class ColorStatistic { + + private String type; + private Color color; + private int number; + private float percentage; + + public ColorStatistic() { + } + + public ColorStatistic(String type, Color color, int number, float percentage) { + this.type = type; + this.color = color; + this.number = number; + this.percentage = percentage; + } + + public static List newSort(List values) { + if (values == null) { + return null; + } + List sorted = new ArrayList<>(); + sorted.addAll(values); + Collections.sort(sorted, new Comparator() { + @Override + public int compare(ColorStatistic p1, ColorStatistic p2) { + return p1.getNumber() - p2.getNumber(); + } + }); + return sorted; + } + + public static void sort(List values) { + if (values == null) { + return; + } + Collections.sort(values, new Comparator() { + @Override + public int compare(ColorStatistic p1, ColorStatistic p2) { + return p1.getNumber() - p2.getNumber(); + } + }); + } + + public static Map statistic(List values) { + Map statistic = new HashMap<>(); + if (values == null) { + return statistic; + } + statistic.put("data", values); + int sum = 0; + for (ColorStatistic s : values) { + sum += s.getNumber(); + } + statistic.put("sum", new ColorStatistic("Sum", null, sum, 100.0f)); + statistic.put("average", new ColorStatistic("Average", null, (int) (sum / values.size()), + ValueTools.roundFloat5(100.0f / values.size()))); + List newList = ColorStatistic.newSort(values); + ColorStatistic s = newList.get(0); + statistic.put("minimum", new ColorStatistic("Minimum", s.getColor(), s.getNumber(), s.getPercentage())); + s = newList.get(newList.size() - 1); + statistic.put("maximum", new ColorStatistic("Maximum", s.getColor(), s.getNumber(), s.getPercentage())); + ColorStatistic median = new ColorStatistic(); + median.setType("Median"); + if (newList.size() % 2 == 0) { + ColorStatistic m1 = newList.get(newList.size() / 2); + ColorStatistic m2 = newList.get(newList.size() / 2 + 1); + median.setColor(m1.getColor()); + median.setNumber((m1.getNumber() + m2.getNumber()) / 2); + } else { + ColorStatistic m = newList.get(newList.size() / 2); + median.setColor(m.getColor()); + median.setNumber(m.getNumber()); + } + median.setPercentage(ValueTools.roundFloat5(median.getNumber() * 100.0f / sum)); + statistic.put("median", median); + return statistic; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public Color getColor() { + return color; + } + + public void setColor(Color color) { + this.color = color; + } + + public int getNumber() { + return number; + } + + public void setNumber(int number) { + this.number = number; + } + + public float getPercentage() { + return percentage; + } + + public void setPercentage(float percentage) { + this.percentage = percentage; + } + +} diff --git a/MyBox/src/main/java/mara/mybox/objects/ConvolutionKernel.java b/MyBox/src/main/java/mara/mybox/data/ConvolutionKernel.java similarity index 97% rename from MyBox/src/main/java/mara/mybox/objects/ConvolutionKernel.java rename to MyBox/src/main/java/mara/mybox/data/ConvolutionKernel.java index 684ae8cc3..1c8832bc4 100644 --- a/MyBox/src/main/java/mara/mybox/objects/ConvolutionKernel.java +++ b/MyBox/src/main/java/mara/mybox/data/ConvolutionKernel.java @@ -1,13 +1,14 @@ -package mara.mybox.objects; +package mara.mybox.data; import java.util.ArrayList; import java.util.Date; import java.util.List; import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.property.SimpleStringProperty; -import mara.mybox.image.ImageConvertTools; +import mara.mybox.image.ImageConvert; import mara.mybox.tools.DateTools; import mara.mybox.tools.ValueTools; +import mara.mybox.value.AppVaribles; /** * @Author Mara @@ -36,8 +37,8 @@ public static class Convolution_Type { public static class Edge_Op { - public static int FILL_ZERO = 0; - public static int COPY = 1; + public static int COPY = 0; + public static int FILL_ZERO = 1; public static int MOD = 2; } @@ -642,49 +643,49 @@ public static float[][] makeGaussMatrix(int radius) { public static float[][] makeEmbossMatrix(int direction, int size) { float[][] m = null; - if (direction == ImageConvertTools.Direction.Top) { + if (direction == ImageConvert.Direction.Top) { if (size == 3) { m = ValueTools.array2Matrix(embossTopKernel, size); } else if (size == 5) { m = ValueTools.array2Matrix(embossTopKernel5, size); } - } else if (direction == ImageConvertTools.Direction.Bottom) { + } else if (direction == ImageConvert.Direction.Bottom) { if (size == 3) { m = ValueTools.array2Matrix(embossBottomKernel, size); } else if (size == 5) { m = ValueTools.array2Matrix(embossBottomKernel5, size); } - } else if (direction == ImageConvertTools.Direction.Left) { + } else if (direction == ImageConvert.Direction.Left) { if (size == 3) { m = ValueTools.array2Matrix(embossLeftKernel, size); } else if (size == 5) { m = ValueTools.array2Matrix(embossLeftKernel5, size); } - } else if (direction == ImageConvertTools.Direction.Right) { + } else if (direction == ImageConvert.Direction.Right) { if (size == 3) { m = ValueTools.array2Matrix(embossRightKernel, size); } else if (size == 5) { m = ValueTools.array2Matrix(embossRightKernel5, size); } - } else if (direction == ImageConvertTools.Direction.LeftTop) { + } else if (direction == ImageConvert.Direction.LeftTop) { if (size == 3) { m = ValueTools.array2Matrix(embossLeftTopKernel, size); } else if (size == 5) { m = ValueTools.array2Matrix(embossLeftTopKernel5, size); } - } else if (direction == ImageConvertTools.Direction.RightBottom) { + } else if (direction == ImageConvert.Direction.RightBottom) { if (size == 3) { m = ValueTools.array2Matrix(embossRightBottomKernel, size); } else if (size == 5) { m = ValueTools.array2Matrix(embossRightBottomKernel5, size); } - } else if (direction == ImageConvertTools.Direction.LeftBottom) { + } else if (direction == ImageConvert.Direction.LeftBottom) { if (size == 3) { m = ValueTools.array2Matrix(embossLeftBottomKernel, size); } else if (size == 5) { m = ValueTools.array2Matrix(embossLeftBottomKernel5, size); } - } else if (direction == ImageConvertTools.Direction.RightTop) { + } else if (direction == ImageConvert.Direction.RightTop) { if (size == 3) { m = ValueTools.array2Matrix(embossRightTopKernel, size); } else if (size == 5) { diff --git a/MyBox/src/main/java/mara/mybox/objects/FileEditInformation.java b/MyBox/src/main/java/mara/mybox/data/FileEditInformation.java similarity index 99% rename from MyBox/src/main/java/mara/mybox/objects/FileEditInformation.java rename to MyBox/src/main/java/mara/mybox/data/FileEditInformation.java index 34379d876..77f4beedc 100644 --- a/MyBox/src/main/java/mara/mybox/objects/FileEditInformation.java +++ b/MyBox/src/main/java/mara/mybox/data/FileEditInformation.java @@ -1,12 +1,13 @@ -package mara.mybox.objects; +package mara.mybox.data; +import mara.mybox.value.AppVaribles; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.nio.charset.Charset; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.logger; import static mara.mybox.tools.TextTools.bomBytes; import static mara.mybox.tools.TextTools.bomSize; import static mara.mybox.tools.TextTools.checkCharsetByBom; diff --git a/MyBox/src/main/java/mara/mybox/objects/FileInformation.java b/MyBox/src/main/java/mara/mybox/data/FileInformation.java similarity index 99% rename from MyBox/src/main/java/mara/mybox/objects/FileInformation.java rename to MyBox/src/main/java/mara/mybox/data/FileInformation.java index fdaf2f246..3d1ae472a 100644 --- a/MyBox/src/main/java/mara/mybox/objects/FileInformation.java +++ b/MyBox/src/main/java/mara/mybox/data/FileInformation.java @@ -1,4 +1,4 @@ -package mara.mybox.objects; +package mara.mybox.data; import java.io.File; import javafx.beans.property.SimpleBooleanProperty; diff --git a/MyBox/src/main/java/mara/mybox/objects/FileSynchronizeAttributes.java b/MyBox/src/main/java/mara/mybox/data/FileSynchronizeAttributes.java similarity index 99% rename from MyBox/src/main/java/mara/mybox/objects/FileSynchronizeAttributes.java rename to MyBox/src/main/java/mara/mybox/data/FileSynchronizeAttributes.java index ec4729fa3..c5714510a 100644 --- a/MyBox/src/main/java/mara/mybox/objects/FileSynchronizeAttributes.java +++ b/MyBox/src/main/java/mara/mybox/data/FileSynchronizeAttributes.java @@ -1,4 +1,4 @@ -package mara.mybox.objects; +package mara.mybox.data; import java.util.List; diff --git a/MyBox/src/main/java/mara/mybox/objects/ImageAttributes.java b/MyBox/src/main/java/mara/mybox/data/ImageAttributes.java similarity index 92% rename from MyBox/src/main/java/mara/mybox/objects/ImageAttributes.java rename to MyBox/src/main/java/mara/mybox/data/ImageAttributes.java index 9cc310faf..9f5d7f6a3 100644 --- a/MyBox/src/main/java/mara/mybox/objects/ImageAttributes.java +++ b/MyBox/src/main/java/mara/mybox/data/ImageAttributes.java @@ -1,4 +1,4 @@ -package mara.mybox.objects; +package mara.mybox.data; import org.apache.pdfbox.rendering.ImageType; @@ -21,7 +21,7 @@ public static class BinaryConversion { private String imageFormat, compressionType; private int density, threshold, quality, binaryConversion, ratioAdjustion; private ImageType colorSpace; - private boolean keepRatio; + private boolean keepRatio, isDithering; private int sourceWidth, sourceHeight, targetWidth, targetHeight; public ImageAttributes() { @@ -139,4 +139,12 @@ public void setSourceHeight(int sourceHeight) { this.sourceHeight = sourceHeight; } + public boolean isIsDithering() { + return isDithering; + } + + public void setIsDithering(boolean isDithering) { + this.isDithering = isDithering; + } + } diff --git a/MyBox/src/main/java/mara/mybox/objects/ImageCombine.java b/MyBox/src/main/java/mara/mybox/data/ImageCombine.java similarity index 97% rename from MyBox/src/main/java/mara/mybox/objects/ImageCombine.java rename to MyBox/src/main/java/mara/mybox/data/ImageCombine.java index 779c4332a..0d50d88ce 100644 --- a/MyBox/src/main/java/mara/mybox/objects/ImageCombine.java +++ b/MyBox/src/main/java/mara/mybox/data/ImageCombine.java @@ -1,7 +1,7 @@ -package mara.mybox.objects; +package mara.mybox.data; import javafx.scene.paint.Color; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.logger; /** diff --git a/MyBox/src/main/java/mara/mybox/objects/ImageFileInformation.java b/MyBox/src/main/java/mara/mybox/data/ImageFileInformation.java similarity index 98% rename from MyBox/src/main/java/mara/mybox/objects/ImageFileInformation.java rename to MyBox/src/main/java/mara/mybox/data/ImageFileInformation.java index daf967877..b0ae45ea4 100644 --- a/MyBox/src/main/java/mara/mybox/objects/ImageFileInformation.java +++ b/MyBox/src/main/java/mara/mybox/data/ImageFileInformation.java @@ -1,4 +1,4 @@ -package mara.mybox.objects; +package mara.mybox.data; import java.io.File; import java.util.List; diff --git a/MyBox/src/main/java/mara/mybox/objects/ImageHistory.java b/MyBox/src/main/java/mara/mybox/data/ImageHistory.java similarity index 97% rename from MyBox/src/main/java/mara/mybox/objects/ImageHistory.java rename to MyBox/src/main/java/mara/mybox/data/ImageHistory.java index 64e2e567f..996f328b9 100644 --- a/MyBox/src/main/java/mara/mybox/objects/ImageHistory.java +++ b/MyBox/src/main/java/mara/mybox/data/ImageHistory.java @@ -1,4 +1,4 @@ -package mara.mybox.objects; +package mara.mybox.data; import java.util.Date; diff --git a/MyBox/src/main/java/mara/mybox/objects/ImageInformation.java b/MyBox/src/main/java/mara/mybox/data/ImageInformation.java similarity index 99% rename from MyBox/src/main/java/mara/mybox/objects/ImageInformation.java rename to MyBox/src/main/java/mara/mybox/data/ImageInformation.java index be12f4615..89442db2b 100644 --- a/MyBox/src/main/java/mara/mybox/objects/ImageInformation.java +++ b/MyBox/src/main/java/mara/mybox/data/ImageInformation.java @@ -1,4 +1,4 @@ -package mara.mybox.objects; +package mara.mybox.data; import java.awt.image.BufferedImage; import java.io.File; diff --git a/MyBox/src/main/java/mara/mybox/objects/ImageManufactureValues.java b/MyBox/src/main/java/mara/mybox/data/ImageManufactureValues.java similarity index 92% rename from MyBox/src/main/java/mara/mybox/objects/ImageManufactureValues.java rename to MyBox/src/main/java/mara/mybox/data/ImageManufactureValues.java index fe9c1e97b..eeee10cbc 100644 --- a/MyBox/src/main/java/mara/mybox/objects/ImageManufactureValues.java +++ b/MyBox/src/main/java/mara/mybox/data/ImageManufactureValues.java @@ -1,9 +1,9 @@ -package mara.mybox.objects; +package mara.mybox.data; +import mara.mybox.image.ImageScope; import java.io.File; +import java.util.Map; import javafx.scene.image.Image; -import static mara.mybox.objects.AppVaribles.logger; - /** * @Author Mara @@ -14,8 +14,6 @@ */ public class ImageManufactureValues { - - private File sourceFile; private ImageScope scope; private File refFile; @@ -23,6 +21,7 @@ public class ImageManufactureValues { private ImageInformation refInfo, imageInfo; private boolean refSync, isConfirmBeforeSave, imageChanged, showRef; private int stageWidth, stageHeight, saveAsType, imageViewWidth, imageViewHeight; + protected Map imageData; public ImageManufactureValues() { } @@ -187,4 +186,12 @@ public void setImageViewHeight(int imageViewHeight) { this.imageViewHeight = imageViewHeight; } + public Map getImageData() { + return imageData; + } + + public void setImageData(Map imageData) { + this.imageData = imageData; + } + } diff --git a/MyBox/src/main/java/mara/mybox/objects/IntCircle.java b/MyBox/src/main/java/mara/mybox/data/IntCircle.java similarity index 97% rename from MyBox/src/main/java/mara/mybox/objects/IntCircle.java rename to MyBox/src/main/java/mara/mybox/data/IntCircle.java index 61f238362..00e27e782 100644 --- a/MyBox/src/main/java/mara/mybox/objects/IntCircle.java +++ b/MyBox/src/main/java/mara/mybox/data/IntCircle.java @@ -1,4 +1,4 @@ -package mara.mybox.objects; +package mara.mybox.data; /** * @Author Mara diff --git a/MyBox/src/main/java/mara/mybox/objects/IntPoint.java b/MyBox/src/main/java/mara/mybox/data/IntPoint.java similarity index 94% rename from MyBox/src/main/java/mara/mybox/objects/IntPoint.java rename to MyBox/src/main/java/mara/mybox/data/IntPoint.java index 47d8ff890..5cf36f0c7 100644 --- a/MyBox/src/main/java/mara/mybox/objects/IntPoint.java +++ b/MyBox/src/main/java/mara/mybox/data/IntPoint.java @@ -1,4 +1,4 @@ -package mara.mybox.objects; +package mara.mybox.data; /** * @Author Mara diff --git a/MyBox/src/main/java/mara/mybox/objects/IntRectangle.java b/MyBox/src/main/java/mara/mybox/data/IntRectangle.java similarity index 98% rename from MyBox/src/main/java/mara/mybox/objects/IntRectangle.java rename to MyBox/src/main/java/mara/mybox/data/IntRectangle.java index 086e4fdef..613336828 100644 --- a/MyBox/src/main/java/mara/mybox/objects/IntRectangle.java +++ b/MyBox/src/main/java/mara/mybox/data/IntRectangle.java @@ -1,4 +1,4 @@ -package mara.mybox.objects; +package mara.mybox.data; /** * @Author Mara diff --git a/MyBox/src/main/java/mara/mybox/data/IntStatistic.java b/MyBox/src/main/java/mara/mybox/data/IntStatistic.java new file mode 100644 index 000000000..8f7019c67 --- /dev/null +++ b/MyBox/src/main/java/mara/mybox/data/IntStatistic.java @@ -0,0 +1,241 @@ +package mara.mybox.data; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import mara.mybox.tools.ValueTools; + +/** + * @Author Mara + * @CreateDate 2019-2-11 12:53:19 + * @Version 1.0 + * @Description + * @License Apache License Version 2.0 + */ +public class IntStatistic { + + private String name; + private long sum; + private int mean, variance, skewness, minimum, maximum, mode; + + public IntStatistic() { + } + + public IntStatistic(String name, long sum, int mean, + int variance, int skewness, int minimum, int maximum, int mode) { + this.name = name; + this.sum = sum; + this.mean = mean; + this.variance = variance; + this.skewness = skewness; + this.minimum = minimum; + this.maximum = maximum; + this.mode = mode; + } + + public static long sum(int[] values) { + long sum = 0; + for (int i = 0; i < values.length; i++) { + sum += values[i]; + } + return sum; + } + + public static int maximum(int[] values) { + if (values == null || values.length == 0) { + return Integer.MIN_VALUE; + } + int max = Integer.MIN_VALUE; + for (int i = 0; i < values.length; i++) { + if (values[i] > max) { + max = values[i]; + } + } + return max; + } + + public static int maximumIndex(int[] values) { + if (values == null || values.length == 0) { + return -1; + } + int max = Integer.MIN_VALUE, maxIndex = -1; + for (int i = 0; i < values.length; i++) { + if (values[i] > max) { + max = values[i]; + maxIndex = i; + } + } + return maxIndex; + } + + public static int minimum(int[] values) { + if (values == null || values.length == 0) { + return Integer.MAX_VALUE; + } + int min = Integer.MAX_VALUE; + for (int i = 0; i < values.length; i++) { + if (values[i] < min) { + min = values[i]; + } + } + return min; + } + + public static long[] sumMaxMin(int[] values) { + long[] s = new long[3]; + if (values == null || values.length == 0) { + return s; + } + int sum = 0, min = Integer.MAX_VALUE, max = Integer.MIN_VALUE; + for (int i = 0; i < values.length; i++) { + sum += values[i]; + if (values[i] > max) { + max = values[i]; + } + if (values[i] < min) { + min = values[i]; + } + } + s[0] = sum; + s[1] = min; + s[2] = max; + return s; + } + + public static int mean(int[] values) { + if (values == null || values.length == 0) { + return 0; + } + return (int) (sum(values) / values.length); + } + + public static int[] median(int[] values) { + int[] mid = new int[3]; + if (values == null || values.length == 0) { + return mid; + } + ValueTools.sortArray(values); + if (values.length % 2 == 0) { + mid[1] = values.length / 2; + mid[2] = values.length / 2 - 1; + mid[0] = (values[mid[1]] + values[mid[2]]) / 2; + } else { + mid[1] = mid[2] = values.length / 2; + mid[0] = values[mid[1]]; + } + return mid; + } + + public static int variance(int[] values) { + int mean = mean(values); + return variance(values, mean); + } + + public static int variance(int[] values, int mean) { + int variance = 0; + for (int i = 0; i < values.length; i++) { + variance += Math.pow(values[i] - mean, 2); + } + variance = (int) Math.sqrt(variance / values.length); + return variance; + } + + public static int skewness(int[] values, int mean) { + int skewness = 0; + for (int i = 0; i < values.length; i++) { + skewness += Math.pow(values[i] - mean, 3); + } + skewness = (int) Math.pow(skewness / values.length, 1.0 / 3); + return skewness; + } + + public static IntValue median(List values) { + if (values == null) { + return null; + } + List sorted = new ArrayList<>(); + sorted.addAll(values); + Collections.sort(sorted, new Comparator() { + @Override + public int compare(IntValue p1, IntValue p2) { + return p1.getValue() - p2.getValue(); + } + }); + IntValue mid = new IntValue(); + + if (sorted.size() % 2 == 0) { + mid.setName(sorted.get(sorted.size() / 2).getName() + " - " + sorted.get(sorted.size() / 2 + 1).getName()); + mid.setValue((sorted.get(sorted.size() / 2).getValue() + sorted.get(sorted.size() / 2 + 1).getValue()) / 2); + } else { + mid.setName(sorted.get(sorted.size() / 2).getName()); + mid.setValue(sorted.get(sorted.size() / 2).getValue()); + } + return mid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public long getSum() { + return sum; + } + + public void setSum(long sum) { + this.sum = sum; + } + + public int getMean() { + return mean; + } + + public void setMean(int mean) { + this.mean = mean; + } + + public int getVariance() { + return variance; + } + + public void setVariance(int variance) { + this.variance = variance; + } + + public int getSkewness() { + return skewness; + } + + public void setSkewness(int skewness) { + this.skewness = skewness; + } + + public int getMinimum() { + return minimum; + } + + public void setMinimum(int minimum) { + this.minimum = minimum; + } + + public int getMaximum() { + return maximum; + } + + public void setMaximum(int maximum) { + this.maximum = maximum; + } + + public int getMode() { + return mode; + } + + public void setMode(int mode) { + this.mode = mode; + } + +} diff --git a/MyBox/src/main/java/mara/mybox/data/IntValue.java b/MyBox/src/main/java/mara/mybox/data/IntValue.java new file mode 100644 index 000000000..189a725f0 --- /dev/null +++ b/MyBox/src/main/java/mara/mybox/data/IntValue.java @@ -0,0 +1,70 @@ +package mara.mybox.data; + +/** + * @Author Mara + * @CreateDate 2019-2-10 12:47:33 + * @Version 1.0 + * @Description + * @License Apache License Version 2.0 + */ +public class IntValue { + + private String type, name; + private int value; + private float percentage; + + public IntValue() { + + } + + public IntValue(int value) { + this.type = null; + this.name = null; + this.value = value; + } + + public IntValue(String name, int value) { + this.type = null; + this.name = name; + this.value = value; + } + + public IntValue(String type, String name, int value) { + this.type = type; + this.name = name; + this.value = value; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getValue() { + return value; + } + + public void setValue(int value) { + this.value = value; + } + + public float getPercentage() { + return percentage; + } + + public void setPercentage(float percentage) { + this.percentage = percentage; + } + +} diff --git a/MyBox/src/main/java/mara/mybox/objects/PdfInformation.java b/MyBox/src/main/java/mara/mybox/data/PdfInformation.java similarity index 98% rename from MyBox/src/main/java/mara/mybox/objects/PdfInformation.java rename to MyBox/src/main/java/mara/mybox/data/PdfInformation.java index 67b003279..2d2ea8f38 100644 --- a/MyBox/src/main/java/mara/mybox/objects/PdfInformation.java +++ b/MyBox/src/main/java/mara/mybox/data/PdfInformation.java @@ -1,10 +1,11 @@ -package mara.mybox.objects; +package mara.mybox.data; +import mara.mybox.value.AppVaribles; import java.awt.image.BufferedImage; import java.io.File; import java.util.Date; import mara.mybox.tools.PdfTools; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.logger; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocumentInformation; diff --git a/MyBox/src/main/java/mara/mybox/objects/TextEditInformation.java b/MyBox/src/main/java/mara/mybox/data/TextEditInformation.java similarity index 99% rename from MyBox/src/main/java/mara/mybox/objects/TextEditInformation.java rename to MyBox/src/main/java/mara/mybox/data/TextEditInformation.java index 65c943d40..dbad136e4 100644 --- a/MyBox/src/main/java/mara/mybox/objects/TextEditInformation.java +++ b/MyBox/src/main/java/mara/mybox/data/TextEditInformation.java @@ -1,11 +1,11 @@ -package mara.mybox.objects; +package mara.mybox.data; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.logger; import mara.mybox.tools.FileTools; import mara.mybox.tools.TextTools; import static mara.mybox.tools.TextTools.bomBytes; diff --git a/MyBox/src/main/java/mara/mybox/objects/WeiboSnapParameters.java b/MyBox/src/main/java/mara/mybox/data/WeiboSnapParameters.java similarity index 95% rename from MyBox/src/main/java/mara/mybox/objects/WeiboSnapParameters.java rename to MyBox/src/main/java/mara/mybox/data/WeiboSnapParameters.java index 1d8354dd7..cb1b276a4 100644 --- a/MyBox/src/main/java/mara/mybox/objects/WeiboSnapParameters.java +++ b/MyBox/src/main/java/mara/mybox/data/WeiboSnapParameters.java @@ -1,5 +1,6 @@ -package mara.mybox.objects; +package mara.mybox.data; +import mara.mybox.value.CommonValues; import java.io.File; import java.util.Date; import mara.mybox.tools.PdfTools.PdfImageFormat; @@ -16,7 +17,7 @@ public class WeiboSnapParameters { private File targetPath; private int webWidth, retry; private boolean imagePerScreen, isImageSize, addPageNumber, createPDF, createHtml, savePictures, keepPagePdf; - private boolean miao, expandComments, expandPicture, fullScreen, openPathWhenStop, useTempFiles; + private boolean miao, expandComments, expandPicture, fullScreen, openPathWhenStop, useTempFiles, dithering; private String webAddress, author, title, fontName; private int marginSize, pageWidth, pageHeight, jpegQuality, threshold, maxMergeSize, category, pdfScale; private Date startMonth, endMonth; @@ -261,7 +262,7 @@ public File getTempdir() { public void setTempdir(File tempdir) { if (tempdir == null || !tempdir.exists() || !tempdir.isDirectory()) { - this.tempdir = new File(CommonValues.UserFilePath); + this.tempdir = CommonValues.AppTempPath; } else { this.tempdir = tempdir; } @@ -299,4 +300,12 @@ public void setFontName(String fontName) { this.fontName = fontName; } + public boolean isDithering() { + return dithering; + } + + public void setDithering(boolean dithering) { + this.dithering = dithering; + } + } diff --git a/MyBox/src/main/java/mara/mybox/db/DerbyBase.java b/MyBox/src/main/java/mara/mybox/db/DerbyBase.java index 1651324d9..25816d196 100644 --- a/MyBox/src/main/java/mara/mybox/db/DerbyBase.java +++ b/MyBox/src/main/java/mara/mybox/db/DerbyBase.java @@ -5,11 +5,10 @@ import java.sql.ResultSet; import java.sql.Statement; import java.util.List; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.ConvolutionKernel; -import static mara.mybox.objects.AppVaribles.logger; - +import mara.mybox.value.AppVaribles; +import mara.mybox.value.CommonValues; +import mara.mybox.data.ConvolutionKernel; +import static mara.mybox.value.AppVaribles.logger; /** * @Author Mara @@ -20,11 +19,9 @@ */ public class DerbyBase { - - protected static final String driver = "org.apache.derby.jdbc.EmbeddedDriver"; protected static final String protocol = "jdbc:derby:"; - protected static final String dbName = CommonValues.DerbyDB; + protected static final String dbName = CommonValues.AppDerbyPath.getAbsolutePath(); protected static final String parameters = ";user=mara;password=mybox;create=true"; protected String Table_Name, Create_Table_Statement; diff --git a/MyBox/src/main/java/mara/mybox/db/TableAlarmClock.java b/MyBox/src/main/java/mara/mybox/db/TableAlarmClock.java index 792a6a698..34571878b 100644 --- a/MyBox/src/main/java/mara/mybox/db/TableAlarmClock.java +++ b/MyBox/src/main/java/mara/mybox/db/TableAlarmClock.java @@ -7,9 +7,9 @@ import java.sql.Statement; import java.util.ArrayList; import java.util.List; -import mara.mybox.objects.AlarmClock; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.CommonValues; +import mara.mybox.data.AlarmClock; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.CommonValues; import mara.mybox.tools.DateTools; /** diff --git a/MyBox/src/main/java/mara/mybox/db/TableBrowserUrls.java b/MyBox/src/main/java/mara/mybox/db/TableBrowserUrls.java index baad8f75a..578adb440 100644 --- a/MyBox/src/main/java/mara/mybox/db/TableBrowserUrls.java +++ b/MyBox/src/main/java/mara/mybox/db/TableBrowserUrls.java @@ -7,7 +7,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.logger; import mara.mybox.tools.DateTools; /** diff --git a/MyBox/src/main/java/mara/mybox/db/TableConvolutionKernel.java b/MyBox/src/main/java/mara/mybox/db/TableConvolutionKernel.java index 55160cf3f..47dc89e0c 100644 --- a/MyBox/src/main/java/mara/mybox/db/TableConvolutionKernel.java +++ b/MyBox/src/main/java/mara/mybox/db/TableConvolutionKernel.java @@ -8,8 +8,8 @@ import java.util.Date; import java.util.List; import static mara.mybox.db.DerbyBase.protocol; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.ConvolutionKernel; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.data.ConvolutionKernel; import mara.mybox.tools.DateTools; /** diff --git a/MyBox/src/main/java/mara/mybox/db/TableFloatMatrix.java b/MyBox/src/main/java/mara/mybox/db/TableFloatMatrix.java index cd3e770f1..04e12942f 100644 --- a/MyBox/src/main/java/mara/mybox/db/TableFloatMatrix.java +++ b/MyBox/src/main/java/mara/mybox/db/TableFloatMatrix.java @@ -7,8 +7,8 @@ import java.util.ArrayList; import java.util.List; import static mara.mybox.db.DerbyBase.protocol; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.ConvolutionKernel; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.data.ConvolutionKernel; /** * @Author Mara diff --git a/MyBox/src/main/java/mara/mybox/db/TableImageHistory.java b/MyBox/src/main/java/mara/mybox/db/TableImageHistory.java index 565b5f9a5..c8066c092 100644 --- a/MyBox/src/main/java/mara/mybox/db/TableImageHistory.java +++ b/MyBox/src/main/java/mara/mybox/db/TableImageHistory.java @@ -8,9 +8,9 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.ImageHistory; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.data.ImageHistory; import mara.mybox.tools.DateTools; /** diff --git a/MyBox/src/main/java/mara/mybox/db/TableImageInit.java b/MyBox/src/main/java/mara/mybox/db/TableImageInit.java index 3a9445cbf..16c8e5104 100644 --- a/MyBox/src/main/java/mara/mybox/db/TableImageInit.java +++ b/MyBox/src/main/java/mara/mybox/db/TableImageInit.java @@ -8,9 +8,9 @@ import java.util.ArrayList; import java.util.Date; import mara.mybox.controller.ImageManufactureController.ImageOperationType; -import mara.mybox.objects.ImageHistory; +import mara.mybox.data.ImageHistory; import mara.mybox.tools.DateTools; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.logger; /** * @Author Mara diff --git a/MyBox/src/main/java/mara/mybox/db/TableSystemConf.java b/MyBox/src/main/java/mara/mybox/db/TableSystemConf.java index afbec64ba..61213daac 100644 --- a/MyBox/src/main/java/mara/mybox/db/TableSystemConf.java +++ b/MyBox/src/main/java/mara/mybox/db/TableSystemConf.java @@ -7,9 +7,9 @@ import java.sql.Statement; import java.util.ArrayList; import java.util.Map; -import mara.mybox.objects.CommonValues; +import mara.mybox.value.CommonValues; import mara.mybox.tools.ConfigTools; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.logger; /** * @Author Mara diff --git a/MyBox/src/main/java/mara/mybox/db/TableUserConf.java b/MyBox/src/main/java/mara/mybox/db/TableUserConf.java index c34c38116..dc0fa5db6 100644 --- a/MyBox/src/main/java/mara/mybox/db/TableUserConf.java +++ b/MyBox/src/main/java/mara/mybox/db/TableUserConf.java @@ -7,9 +7,9 @@ import java.sql.Statement; import java.util.ArrayList; import java.util.Map; -import mara.mybox.objects.CommonValues; +import mara.mybox.value.CommonValues; import mara.mybox.tools.ConfigTools; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.logger; /** * @Author Mara diff --git a/MyBox/src/main/java/mara/mybox/fxml/FxmlAdjustColorTools.java b/MyBox/src/main/java/mara/mybox/fxml/FxmlAdjustColorTools.java deleted file mode 100644 index 5996f9195..000000000 --- a/MyBox/src/main/java/mara/mybox/fxml/FxmlAdjustColorTools.java +++ /dev/null @@ -1,456 +0,0 @@ -package mara.mybox.fxml; - -import java.util.LinkedList; -import java.util.List; -import java.util.Queue; -import javafx.scene.image.Image; -import javafx.scene.image.PixelReader; -import javafx.scene.image.PixelWriter; -import javafx.scene.image.WritableImage; -import javafx.scene.paint.Color; -import mara.mybox.objects.ImageScope; -import mara.mybox.objects.IntPoint; -import static mara.mybox.objects.AppVaribles.logger; - - -/** - * @Author Mara - * @CreateDate 2018-11-10 19:32:00 - * @Version 1.0 - * @Description - * @License Apache License Version 2.0 - */ -public class FxmlAdjustColorTools { - - - - public enum ColorObjectType { - Brightness, Sauration, Hue, Opacity, Red, Green, Blue, Yellow, Cyan, Magenta, RGB, Color - } - - public enum ColorActionType { - Increase, Decrease, Set, Filter, Invert - } - - public static Image ajustColor(Image source, ColorObjectType objectType, ColorActionType actionType, - double change, Color inColor, ImageScope scope) { - if (actionType == ColorActionType.Decrease) { - change = 0 - change; - } - if (scope.getScopeType() == ImageScope.ScopeType.Matting) { - if (objectType == ColorObjectType.Color) { - return setColorByMatting(source, inColor, scope); - } else { - return changeColorByMatting(source, objectType, actionType, change, scope); - } - } else { - if (objectType == ColorObjectType.Color) { - return setColorByScope(source, inColor, scope); - } else { - return changeColorByScope(source, objectType, actionType, change, scope); - } - } - } - - public static Image setColorByScope(Image source, - Color newColor, ImageScope scope) { - PixelReader pixelReader = source.getPixelReader(); - WritableImage newImage = new WritableImage((int) source.getWidth(), (int) source.getHeight()); - PixelWriter pixelWriter = newImage.getPixelWriter(); - - for (int y = 0; y < source.getHeight(); y++) { - for (int x = 0; x < source.getWidth(); x++) { - Color color = pixelReader.getColor(x, y); - if (scope == null || scope.inScope(x, y, color)) { - pixelWriter.setColor(x, y, newColor); - } else { - pixelWriter.setColor(x, y, color); - } - } - } - return newImage; - } - - public static Image setColorByMatting(Image source, Color newColor, ImageScope scope) { - try { - if (source == null) { - return source; - } - List points = scope.getPoints(); - double distance = scope.getColorDistance(); - if (points == null || points.isEmpty() - || distance < 0 || distance > 1) { - return source; - } - - int width = (int) source.getWidth(); - int height = (int) source.getHeight(); - PixelReader pixelReader = source.getPixelReader(); - WritableImage newImage = new WritableImage(width, height); - PixelWriter pixelWriter = newImage.getPixelWriter(); - - boolean excluded = scope.isColorExcluded(); - if (excluded) { - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - Color color = pixelReader.getColor(x, y); - if (color == Color.TRANSPARENT) { - pixelWriter.setColor(x, y, color); - continue; - } - pixelWriter.setColor(x, y, newColor); - } - } - } else { - pixelWriter.setPixels(0, 0, width, height, pixelReader, 0, 0); - } - - boolean[][] visited = new boolean[height][width]; - Queue queue = new LinkedList<>(); - for (IntPoint point : points) { - Color startColor = pixelReader.getColor(point.getX(), point.getY()); - queue.add(point); - while (!queue.isEmpty()) { - IntPoint p = queue.remove(); - int x = p.getX(), y = p.getY(); - if (x < 0 || x >= width || y < 0 || y >= height - || visited[y][x]) { - continue; - } - visited[y][x] = true; - Color color = pixelReader.getColor(x, y); - if (FxmlColorTools.isColorMatch(color, startColor, distance)) { - if (excluded) { - pixelWriter.setColor(x, y, color); - } else { - pixelWriter.setColor(x, y, newColor); - } - queue.add(new IntPoint(x + 1, y)); - queue.add(new IntPoint(x - 1, y)); - queue.add(new IntPoint(x, y + 1)); - queue.add(new IntPoint(x, y - 1)); - } - } - } - - return newImage; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - - } - - public static Image changeColorByScope(Image source, - ColorObjectType objectType, ColorActionType actionType, - double change, ImageScope scope) { - PixelReader pixelReader = source.getPixelReader(); - WritableImage newImage = new WritableImage((int) source.getWidth(), (int) source.getHeight()); - PixelWriter pixelWriter = newImage.getPixelWriter(); - - Color newColor; - for (int y = 0; y < source.getHeight(); y++) { - for (int x = 0; x < source.getWidth(); x++) { - Color color = pixelReader.getColor(x, y); - if (color == Color.TRANSPARENT) { - pixelWriter.setColor(x, y, color); - } else if (scope == null || scope.inScope(x, y, color)) { - newColor = changeColor(color, objectType, actionType, change); - pixelWriter.setColor(x, y, newColor); - } else { - pixelWriter.setColor(x, y, color); - } - } - } - return newImage; - } - - public static Image changeColorByMatting(Image source, - ColorObjectType objectType, ColorActionType actionType, - double change, ImageScope scope) { - try { - if (source == null) { - return source; - } - List points = scope.getPoints(); - double distance = scope.getColorDistance(); - if (points == null || points.isEmpty() - || distance < 0 || distance > 1) { - return source; - } - - int width = (int) source.getWidth(); - int height = (int) source.getHeight(); - PixelReader pixelReader = source.getPixelReader(); - WritableImage newImage = new WritableImage(width, height); - PixelWriter pixelWriter = newImage.getPixelWriter(); - - boolean excluded = scope.isColorExcluded(); - if (excluded) { - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - Color color = pixelReader.getColor(x, y); - if (color == Color.TRANSPARENT) { - pixelWriter.setColor(x, y, color); - continue; - } - Color newColor = changeColor(color, objectType, actionType, change); - pixelWriter.setColor(x, y, newColor); - } - } - } else { - pixelWriter.setPixels(0, 0, width, height, pixelReader, 0, 0); - } - - boolean[][] visited = new boolean[height][width]; - Queue queue = new LinkedList<>(); - Color newColor; - for (IntPoint point : points) { - Color startColor = pixelReader.getColor(point.getX(), point.getY()); - queue.add(point); - while (!queue.isEmpty()) { - IntPoint p = queue.remove(); - int x = p.getX(), y = p.getY(); - if (x < 0 || x >= width || y < 0 || y >= height - || visited[y][x]) { - continue; - } - visited[y][x] = true; - Color color = pixelReader.getColor(x, y); - if (color != Color.TRANSPARENT - && FxmlColorTools.isColorMatch(color, startColor, distance)) { - if (excluded) { - pixelWriter.setColor(x, y, color); - } else { - newColor = changeColor(color, objectType, actionType, change); - pixelWriter.setColor(x, y, newColor); - } - queue.add(new IntPoint(x + 1, y)); - queue.add(new IntPoint(x - 1, y)); - queue.add(new IntPoint(x, y + 1)); - queue.add(new IntPoint(x, y - 1)); - } - } - } - - return newImage; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - - } - - public static Color changeColor(Color color, - ColorObjectType type, ColorActionType actionType, - double change) { - Color newColor = color; - double v, red, blue, green; - switch (type) { - case Brightness: - if (actionType == ColorActionType.Set) { - v = change; - } else { - v = color.getBrightness() * (1.0 + change); - } - v = Math.min(Math.max(v, 0.0), 1.0); - newColor = Color.hsb(color.getHue(), color.getSaturation(), v, color.getOpacity()); - break; - case Sauration: - if (actionType == ColorActionType.Set) { - v = change; - } else { - v = color.getSaturation() * (1.0 + change); - } - v = Math.min(Math.max(v, 0.0), 1.0); - newColor = Color.hsb(color.getHue(), v, color.getBrightness(), color.getOpacity()); - break; - case Hue: - if (actionType == ColorActionType.Set) { - v = change; - } else { - v = color.getHue() + change; - } - if (v > 360.0) { - v = v - 360.0; - } - if (v < 0.0) { - v = v + 360.0; - } - newColor = Color.hsb(v, color.getSaturation(), color.getBrightness(), color.getOpacity()); - break; - case Opacity: - v = Math.min(Math.max(change, 0.0), 1.0); - newColor = new Color(color.getRed(), color.getGreen(), color.getBlue(), v); - break; - case Red: - switch (actionType) { - case Set: - red = change; - red = Math.min(Math.max(red, 0.0), 1.0); - newColor = new Color(red, color.getGreen(), color.getBlue(), color.getOpacity()); - break; - case Increase: - case Decrease: - red = color.getRed() + change; - red = Math.min(Math.max(red, 0.0), 1.0); - newColor = new Color(red, color.getGreen(), color.getBlue(), color.getOpacity()); - break; - case Filter: - newColor = new Color(color.getRed(), 0, 0, color.getOpacity()); - break; - case Invert: - newColor = new Color(1.0 - color.getRed(), color.getGreen(), color.getBlue(), color.getOpacity()); - break; - } - break; - case Green: - switch (actionType) { - case Set: - green = change; - green = Math.min(Math.max(green, 0.0), 1.0); - newColor = new Color(color.getRed(), green, color.getBlue(), color.getOpacity()); - break; - case Increase: - case Decrease: - green = color.getGreen() + change; - green = Math.min(Math.max(green, 0.0), 1.0); - newColor = new Color(color.getRed(), green, color.getBlue(), color.getOpacity()); - break; - case Filter: - newColor = new Color(0, color.getGreen(), 0, color.getOpacity()); - break; - case Invert: - newColor = new Color(color.getRed(), 1.0 - color.getGreen(), color.getBlue(), color.getOpacity()); - break; - } - break; - case Blue: - switch (actionType) { - case Set: - blue = change; - blue = Math.min(Math.max(blue, 0.0), 1.0); - newColor = new Color(color.getRed(), color.getGreen(), blue, color.getOpacity()); - break; - case Increase: - case Decrease: - blue = color.getBlue() + change; - blue = Math.min(Math.max(blue, 0.0), 1.0); - newColor = new Color(color.getRed(), color.getGreen(), blue, color.getOpacity()); - break; - case Filter: - newColor = new Color(0, 0, color.getBlue(), color.getOpacity()); - break; - case Invert: - newColor = new Color(color.getRed(), color.getGreen(), 1.0 - color.getBlue(), color.getOpacity()); - break; - } - break; - case Yellow: - switch (actionType) { - case Set: - red = change; - green = change; - red = Math.min(Math.max(red, 0.0), 1.0); - green = Math.min(Math.max(green, 0.0), 1.0); - newColor = new Color(red, green, color.getBlue(), color.getOpacity()); - break; - case Increase: - case Decrease: - red = color.getRed() + change; - green = color.getGreen() + change; - red = Math.min(Math.max(red, 0.0), 1.0); - green = Math.min(Math.max(green, 0.0), 1.0); - newColor = new Color(red, green, color.getBlue(), color.getOpacity()); - break; - case Filter: - newColor = new Color(color.getRed(), color.getGreen(), 0, color.getOpacity()); - break; - case Invert: - newColor = new Color(1.0 - color.getRed(), 1.0 - color.getGreen(), color.getBlue(), color.getOpacity()); - break; - } - break; - case Cyan: - switch (actionType) { - case Set: - blue = change; - green = change; - blue = Math.min(Math.max(blue, 0.0), 1.0); - green = Math.min(Math.max(green, 0.0), 1.0); - newColor = new Color(color.getRed(), green, blue, color.getOpacity()); - break; - case Increase: - case Decrease: - blue = color.getBlue() + change; - green = color.getGreen() + change; - blue = Math.min(Math.max(blue, 0.0), 1.0); - green = Math.min(Math.max(green, 0.0), 1.0); - newColor = new Color(color.getRed(), green, blue, color.getOpacity()); - break; - case Filter: - newColor = new Color(0, color.getGreen(), color.getBlue(), color.getOpacity()); - break; - case Invert: - newColor = new Color(color.getRed(), 1.0 - color.getGreen(), 1.0 - color.getBlue(), color.getOpacity()); - break; - } - break; - case Magenta: - switch (actionType) { - case Set: - blue = change; - red = change; - blue = Math.min(Math.max(blue, 0.0), 1.0); - red = Math.min(Math.max(red, 0.0), 1.0); - newColor = new Color(red, color.getGreen(), blue, color.getOpacity()); - break; - case Increase: - case Decrease: - blue = color.getBlue() + change; - red = color.getRed() + change; - blue = Math.min(Math.max(blue, 0.0), 1.0); - red = Math.min(Math.max(red, 0.0), 1.0); - newColor = new Color(red, color.getGreen(), blue, color.getOpacity()); - break; - case Filter: - newColor = new Color(color.getRed(), 0, color.getBlue(), color.getOpacity()); - break; - case Invert: - newColor = new Color(1.0 - color.getRed(), color.getGreen(), 1.0 - color.getBlue(), color.getOpacity()); - break; - } - break; - case RGB: - switch (actionType) { - case Set: - blue = change; - green = change; - red = change; - blue = Math.min(Math.max(blue, 0.0), 1.0); - green = Math.min(Math.max(green, 0.0), 1.0); - red = Math.min(Math.max(red, 0.0), 1.0); - newColor = new Color(red, green, blue, color.getOpacity()); - break; - case Increase: - case Decrease: - blue = color.getBlue() + change; - green = color.getGreen() + change; - red = color.getRed() + change; - blue = Math.min(Math.max(blue, 0.0), 1.0); - green = Math.min(Math.max(green, 0.0), 1.0); - red = Math.min(Math.max(red, 0.0), 1.0); - newColor = new Color(red, green, blue, color.getOpacity()); - break; - case Invert: - newColor = color.invert(); - break; - } - break; - default: - break; - } - return newColor; - } - -} diff --git a/MyBox/src/main/java/mara/mybox/fxml/FxmlColor.java b/MyBox/src/main/java/mara/mybox/fxml/FxmlColor.java new file mode 100644 index 000000000..0dac1c3b0 --- /dev/null +++ b/MyBox/src/main/java/mara/mybox/fxml/FxmlColor.java @@ -0,0 +1,29 @@ +package mara.mybox.fxml; + +import javafx.scene.paint.Color; + +/** + * @Author Mara + * @CreateDate 2018-11-13 12:38:14 + * @Version 1.0 + * @Description + * @License Apache License Version 2.0 + */ +public class FxmlColor { + + public static String rgb2Hex(Color color) { + return String.format("#%02X%02X%02X", + (int) (color.getRed() * 255), + (int) (color.getGreen() * 255), + (int) (color.getBlue() * 255)); + } + + public static String rgb2AlphaHex(Color color) { + return String.format("#%02X%02X%02X%02X", + (int) (color.getOpacity() * 255), + (int) (color.getRed() * 255), + (int) (color.getGreen() * 255), + (int) (color.getBlue() * 255)); + } + +} diff --git a/MyBox/src/main/java/mara/mybox/fxml/FxmlColorTools.java b/MyBox/src/main/java/mara/mybox/fxml/FxmlColorTools.java deleted file mode 100644 index 9f5f08eb4..000000000 --- a/MyBox/src/main/java/mara/mybox/fxml/FxmlColorTools.java +++ /dev/null @@ -1,133 +0,0 @@ -package mara.mybox.fxml; - -import javafx.scene.paint.Color; - -/** - * @Author Mara - * @CreateDate 2018-11-13 12:38:14 - * @Version 1.0 - * @Description - * @License Apache License Version 2.0 - */ -public class FxmlColorTools { - - public static String rgb2Hex(Color color) { - return String.format("#%02X%02X%02X", - (int) (color.getRed() * 255), - (int) (color.getGreen() * 255), - (int) (color.getBlue() * 255)); - } - - public static String rgb2AlphaHex(Color color) { - return String.format("#%02X%02X%02X%02X", - (int) (color.getOpacity() * 255), - (int) (color.getRed() * 255), - (int) (color.getGreen() * 255), - (int) (color.getBlue() * 255)); - } - - // https://en.wikipedia.org/wiki/Color_difference - public static double calculateColorDistance2(Color color1, Color color2) { - if (color1 == color2) { - return 0; - } - double v = 2 * Math.pow(color1.getRed() - color2.getRed(), 2) - + 4 * Math.pow(color1.getGreen() - color2.getGreen(), 2) - + 3 * Math.pow(color1.getBlue() - color2.getBlue(), 2); - return v; - } - - //distance: 0.0 - 1.0 - public static boolean isColorMatch(Color color1, Color color2, double distance) { - if (color1 == color2) { - return true; - } else if (distance == 0) { - return false; - } - return calculateColorDistance2(color1, color2) <= Math.pow(distance, 2); - } - - public static boolean isRedMatch(Color color1, Color color2, double distance) { - return Math.abs(color1.getRed() - color2.getRed()) <= distance; - } - - public static boolean isGreenMatch(Color color1, Color color2, double distance) { - return Math.abs(color1.getGreen() - color2.getGreen()) <= distance; - } - - public static boolean isBlueMatch(Color color1, Color color2, double distance) { - return Math.abs(color1.getBlue() - color2.getBlue()) <= distance; - } - - public static boolean isHueMatch(Color color1, Color color2, int distance) { - return Math.abs(color1.getHue() - color2.getHue()) <= distance; - } - - public static boolean isBrightnessMatch(Color color1, Color color2, double distance) { - return Math.abs(color1.getBrightness() - color2.getBrightness()) <= distance; - } - - public static boolean isSaturationMatch(Color color1, Color color2, double distance) { - return Math.abs(color1.getSaturation() - color2.getSaturation()) <= distance; - } - - public static Color thresholdingColor(Color inColor, - int threshold, int smallValue, int bigValue) { - if (inColor == Color.TRANSPARENT) { - return inColor; - } - double red, green, blue; - double thresholdDouble = threshold / 255.0, smallDouble = smallValue / 255.0, bigDouble = bigValue / 255.0; - if (inColor.getRed() < thresholdDouble) { - red = smallDouble; - } else { - red = bigDouble; - } - if (inColor.getGreen() < thresholdDouble) { - green = smallDouble; - } else { - green = bigDouble; - } - if (inColor.getBlue() < thresholdDouble) { - blue = smallDouble; - } else { - blue = bigDouble; - } - Color newColor = new Color(red, green, blue, inColor.getOpacity()); - return newColor; - } - - public static Color posterizingColor(Color inColor, int size) { - if (inColor == Color.TRANSPARENT) { - return inColor; - } - double red, green, blue; - - int v = (int) (inColor.getRed() * 255); - v = v - (v % size); - red = Math.min(Math.max(v / 255.0, 0.0), 1.0); - - v = (int) (inColor.getGreen() * 255); - v = v - (v % size); - green = Math.min(Math.max(v / 255.0, 0.0), 1.0); - - v = (int) (inColor.getBlue() * 255); - v = v - (v % size); - blue = Math.min(Math.max(v / 255.0, 0.0), 1.0); - - Color newColor = new Color(red, green, blue, inColor.getOpacity()); - return newColor; - } - - public static Color pixel2Sepia(Color color, double sepiaIntensity) { - double sepiaDepth = 20; - double gray = color.grayscale().getRed() * 255; - double r = gray, g = gray, b = gray; - r = Math.min(r + (sepiaDepth * 2), 255); - g = Math.min(g + sepiaDepth, 255); - b = Math.min(Math.max(b - sepiaIntensity, 0), 255); - Color newColor = new Color(r / 255.0f, g / 255.0f, b / 255.0f, color.getOpacity()); - return newColor; - } - -} diff --git a/MyBox/src/main/java/mara/mybox/fxml/FxmlEffectTools.java b/MyBox/src/main/java/mara/mybox/fxml/FxmlEffectTools.java deleted file mode 100644 index 826ce505e..000000000 --- a/MyBox/src/main/java/mara/mybox/fxml/FxmlEffectTools.java +++ /dev/null @@ -1,698 +0,0 @@ -package mara.mybox.fxml; - -import java.awt.image.BufferedImage; -import java.util.LinkedList; -import java.util.List; -import java.util.Queue; -import javafx.embed.swing.SwingFXUtils; -import javafx.scene.image.Image; -import javafx.scene.image.PixelReader; -import javafx.scene.image.PixelWriter; -import javafx.scene.image.WritableImage; -import javafx.scene.paint.Color; -import mara.mybox.image.ImageConvertTools; -import mara.mybox.image.ImageEffectTools; -import mara.mybox.objects.ConvolutionKernel; -import mara.mybox.objects.ImageScope; -import mara.mybox.objects.IntPoint; -import static mara.mybox.objects.AppVaribles.logger; - - -/** - * @Author Mara - * @CreateDate 2018-11-10 19:35:49 - * @Version 1.0 - * @Description - * @License Apache License Version 2.0 - */ -public class FxmlEffectTools { - - - - public enum EffectsOperationType { - Blur, Sharpen, Clarity, Emboss, EdgeDetect, Thresholding, Posterizing, Gray, BlackOrWhite, Sepia - } - - public static Image applyConvolution(Image image, ConvolutionKernel kernel, ImageScope scope) { - if (image == null) { - return null; - } - if (scope == null || scope.getScopeType() == ImageScope.ScopeType.All) { - return applyConvolution(image, kernel); - } else if (scope.getScopeType() == ImageScope.ScopeType.Matting) { - return applyConvolutionByMatting(image, kernel, scope); - } else { - return applyConvolutionByScope(image, kernel, scope); - } - } - - public static Image applyConvolution(Image image, ConvolutionKernel kernel) { - if (image == null) { - return null; - } - BufferedImage source = SwingFXUtils.fromFXImage(image, null); - BufferedImage target = ImageEffectTools.applyConvolution(source, kernel); - Image newImage = SwingFXUtils.toFXImage(target, null); - return newImage; - } - - public static Image applyConvolutionByScope(Image image, ConvolutionKernel kernel, ImageScope scope) { - if (image == null || scope == null || kernel == null || kernel.getMatrix() == null) { - return image; - } - int imageWidth = (int) image.getWidth(); - int imageHeight = (int) image.getHeight(); - PixelReader pixelReader = image.getPixelReader(); - WritableImage newImage = new WritableImage(imageWidth, imageHeight); - PixelWriter pixelWriter = newImage.getPixelWriter(); - - float[][] matrix = kernel.getMatrix(); - int edge_op = kernel.getEdge(); - int radiusX = matrix[0].length / 2, radiusY = matrix.length / 2, - maxX = imageWidth - 1, maxY = imageHeight - 1; - boolean isEmboss = (kernel.getType() == ConvolutionKernel.Convolution_Type.EMBOSS); - boolean isGray = (kernel.getGray() > 0); - boolean keepOpacity = (kernel.getType() != ConvolutionKernel.Convolution_Type.EMBOSS - && kernel.getType() != ConvolutionKernel.Convolution_Type.EDGE_DETECTION); - for (int y = 0; y < image.getHeight(); y++) { - for (int x = 0; x < image.getWidth(); x++) { - Color color = pixelReader.getColor(x, y); - if (color == Color.TRANSPARENT) { - pixelWriter.setColor(x, y, color); - continue; - } - if (scope.inScope(x, y, color)) { - if (x < radiusX || x + radiusX > maxX - || y < radiusY || y + radiusY > maxY) { - if (edge_op == ConvolutionKernel.Edge_Op.COPY) { - pixelWriter.setColor(x, y, color); - continue; - } - } - Color newColor = FxmlEffectTools.applyConvolution(pixelReader, imageWidth, imageHeight, - matrix, edge_op, keepOpacity, x, y); - if (isEmboss) { - double v = 128.0 / 255, red, blue, green; - red = Math.min(Math.max(newColor.getRed() + v, 0.0), 1.0); - green = Math.min(Math.max(newColor.getGreen() + v, 0.0), 1.0); - blue = Math.min(Math.max(newColor.getBlue() + v, 0.0), 1.0); - newColor = new Color(red, green, blue, newColor.getOpacity()); - if (isGray) { - newColor = newColor.grayscale(); - } - } - pixelWriter.setColor(x, y, newColor); - } else { - pixelWriter.setColor(x, y, color); - } - } - } - return newImage; - } - - public static Image applyConvolutionByMatting(Image source, ConvolutionKernel kernel, ImageScope scope) { - try { - if (source == null) { - return source; - } - List points = scope.getPoints(); - double distance = scope.getColorDistance(); - if (points == null || points.isEmpty() - || distance < 0 || distance > 1) { - return source; - } - - int imageWidth = (int) source.getWidth(); - int imageHeight = (int) source.getHeight(); - PixelReader pixelReader = source.getPixelReader(); - WritableImage newImage = new WritableImage(imageWidth, imageHeight); - PixelWriter pixelWriter = newImage.getPixelWriter(); - - boolean excluded = scope.isColorExcluded(); - float[][] matrix = kernel.getMatrix(); - int radiusX = matrix[0].length / 2, radiusY = matrix.length / 2, - maxX = imageWidth - 1, maxY = imageHeight - 1; - boolean keepOpacity = (kernel.getType() != ConvolutionKernel.Convolution_Type.EMBOSS - && kernel.getType() != ConvolutionKernel.Convolution_Type.EDGE_DETECTION); - boolean isEmboss = (kernel.getType() == ConvolutionKernel.Convolution_Type.EMBOSS); - boolean isGray = (kernel.getGray() > 0); - - if (excluded) { - for (int y = 0; y < imageHeight; y++) { - for (int x = 0; x < imageWidth; x++) { - applyConvolutionByMatting(pixelReader, pixelWriter, kernel, scope, imageWidth, imageHeight, - radiusX, radiusY, maxX, maxY, keepOpacity, isEmboss, isGray, - x, y); - } - } - } else { - pixelWriter.setPixels(0, 0, imageWidth, imageHeight, pixelReader, 0, 0); - } - - boolean[][] visited = new boolean[imageHeight][imageWidth]; - Queue queue = new LinkedList<>(); - - for (IntPoint point : points) { - Color startColor = pixelReader.getColor(point.getX(), point.getY()); - queue.add(point); - while (!queue.isEmpty()) { - IntPoint p = queue.remove(); - int x = p.getX(), y = p.getY(); - if (x < 0 || x >= imageWidth || y < 0 || y >= imageHeight - || visited[y][x]) { - continue; - } - visited[y][x] = true; - Color color = pixelReader.getColor(x, y); - if (FxmlColorTools.isColorMatch(color, startColor, distance)) { - if (excluded) { - pixelWriter.setColor(x, y, color); - } else { - applyConvolutionByMatting(pixelReader, pixelWriter, kernel, scope, imageWidth, imageHeight, - radiusX, radiusY, maxX, maxY, keepOpacity, isEmboss, isGray, - x, y); - } - queue.add(new IntPoint(x + 1, y)); - queue.add(new IntPoint(x - 1, y)); - queue.add(new IntPoint(x, y + 1)); - queue.add(new IntPoint(x, y - 1)); - } - } - } - - return newImage; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - } - - public static void applyConvolutionByMatting(PixelReader pixelReader, PixelWriter pixelWriter, - ConvolutionKernel kernel, ImageScope scope, - int imageWidth, int imageHeight, - int radiusX, int radiusY, int maxX, int maxY, - boolean keepOpacity, boolean isEmboss, boolean isGray, - int x, int y) { - float[][] matrix = kernel.getMatrix(); - int edge_op = kernel.getEdge(); - Color color = pixelReader.getColor(x, y); - if (color == Color.TRANSPARENT) { - pixelWriter.setColor(x, y, color); - return; - } - if (x < radiusX || x + radiusX > maxX - || y < radiusY || y + radiusY > maxY) { - if (edge_op == ConvolutionKernel.Edge_Op.COPY) { - pixelWriter.setColor(x, y, color); - return; - } - } - Color newColor = applyConvolution(pixelReader, imageWidth, imageHeight, - matrix, edge_op, keepOpacity, x, y); - if (isEmboss) { - double v = 128.0 / 255, red, blue, green; - red = Math.min(Math.max(newColor.getRed() + v, 0.0), 1.0); - green = Math.min(Math.max(newColor.getGreen() + v, 0.0), 1.0); - blue = Math.min(Math.max(newColor.getBlue() + v, 0.0), 1.0); - newColor = new Color(red, green, blue, newColor.getOpacity()); - if (isGray) { - newColor = newColor.grayscale(); - } - } - pixelWriter.setColor(x, y, newColor); - } - - public static Color applyConvolution(PixelReader pixelReader, int imageWidth, int imageHeight, - float[][] matrix, int edge_op, boolean keepOpacity, int x, int y) { - if (pixelReader == null || matrix == null || matrix.length == 0) { - return null; - } - try { - int matrixWidth = matrix[0].length; - int matrixHeight = matrix.length; - double red = 0.0, green = 0.0, blue = 0.0, opacity = 0.0; - int convolveX, convolveY, radiusX = matrixWidth / 2, radiusY = matrixHeight / 2, - maxX = imageWidth - 1, maxY = imageHeight - 1; - for (int matrixY = 0; matrixY < matrixHeight; matrixY++) { - for (int matrixX = 0; matrixX < matrixWidth; matrixX++) { - convolveX = x - radiusX + matrixX; - convolveY = y - radiusY + matrixY; - if (convolveX < 0 || convolveX > maxX || convolveY < 0 || convolveY > maxY) { - if (edge_op == ConvolutionKernel.Edge_Op.MOD) { - convolveX = (convolveX + imageWidth) % imageWidth; - convolveY = (convolveY + imageHeight) % imageHeight; - } else { - continue; // Fill_zero - } - } - Color color = pixelReader.getColor(convolveX, convolveY); - red += color.getRed() * matrix[matrixY][matrixX]; - green += color.getGreen() * matrix[matrixY][matrixX]; - blue += color.getBlue() * matrix[matrixY][matrixX]; - if (keepOpacity) { - opacity += color.getOpacity() * matrix[matrixY][matrixX]; - } - } - } - red = Math.min(Math.max(red, 0), 1.0); - green = Math.min(Math.max(green, 0), 1.0); - blue = Math.min(Math.max(blue, 0), 1.0); - if (keepOpacity) { - opacity = Math.min(Math.max(opacity, 0), 1.0); - } else { - opacity = 1.0; - } - Color color = new Color(red, green, blue, opacity); - return color; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - - } - - public static Image applyConvolution(Image image, float[][] kernel, int edge_op, boolean keepOpacity) { - if (image == null || kernel == null || kernel.length == 0) { - return image; - } - try { - int imageWidth = (int) image.getWidth(); - int imageHeight = (int) image.getHeight(); - PixelReader pixelReader = image.getPixelReader(); - WritableImage newImage = new WritableImage(imageWidth, imageHeight); - PixelWriter pixelWriter = newImage.getPixelWriter(); - - for (int j = 0; j < imageHeight; j++) { - for (int i = 0; i < imageWidth; i++) { - Color newColor = FxmlEffectTools.applyConvolution(pixelReader, imageWidth, imageHeight, - kernel, edge_op, keepOpacity, i, j); - pixelWriter.setColor(i, j, newColor); - } - } - return newImage; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - - } - - public static Image applyMatrix(Image image, float[][] matrix, boolean removeAlpha) { - if (image == null) { - return null; - } - BufferedImage source = SwingFXUtils.fromFXImage(image, null); - BufferedImage target; - if (removeAlpha) { - target = ImageEffectTools.applyMatrix(ImageConvertTools.clearAlpha(source), matrix); - } else { - target = ImageEffectTools.applyMatrix(source, matrix); - } - Image newImage = SwingFXUtils.toFXImage(target, null); - return newImage; - - } - - public static Image posterizingImage(Image image, int size, ImageScope scope) { - if (image == null || size < 0) { - return image; - } - if (scope == null || scope.getScopeType() == ImageScope.ScopeType.All) { - return FxmlEffectTools.posterizingImage(image, size); - } else if (scope.getScopeType() == ImageScope.ScopeType.Matting) { - return FxmlEffectTools.posterizingByMatting(image, size, scope); - } else { - return FxmlEffectTools.posterizingByScope(image, size, scope); - } - } - - public static Image posterizingImage(Image image, int size) { - if (image == null || size < 0) { - return image; - } - int imageWidth = (int) image.getWidth(); - int imageHeight = (int) image.getHeight(); - PixelReader pixelReader = image.getPixelReader(); - WritableImage newImage = new WritableImage(imageWidth, imageHeight); - PixelWriter pixelWriter = newImage.getPixelWriter(); - - for (int y = 0; y < image.getHeight(); y++) { - for (int x = 0; x < image.getWidth(); x++) { - Color color = pixelReader.getColor(x, y); - Color newColor = FxmlColorTools.posterizingColor(color, size); - pixelWriter.setColor(x, y, newColor); - } - } - return newImage; - } - - public static Image posterizingByScope(Image image, int size, ImageScope scope) { - if (image == null || size < 0 || scope == null) { - return image; - } - int imageWidth = (int) image.getWidth(); - int imageHeight = (int) image.getHeight(); - PixelReader pixelReader = image.getPixelReader(); - WritableImage newImage = new WritableImage(imageWidth, imageHeight); - PixelWriter pixelWriter = newImage.getPixelWriter(); - - for (int y = 0; y < image.getHeight(); y++) { - for (int x = 0; x < image.getWidth(); x++) { - Color color = pixelReader.getColor(x, y); - if (scope.inScope(x, y, color)) { - Color newColor = FxmlColorTools.posterizingColor(color, size); - pixelWriter.setColor(x, y, newColor); - } else { - pixelWriter.setColor(x, y, color); - } - } - } - return newImage; - } - - public static Image posterizingByMatting(Image source, int size, ImageScope scope) { - try { - if (source == null || size < 0 || scope == null) { - return source; - } - List points = scope.getPoints(); - double distance = scope.getColorDistance(); - if (points == null || points.isEmpty() - || distance < 0 || distance > 1) { - return source; - } - int imageWidth = (int) source.getWidth(); - int imageHeight = (int) source.getHeight(); - PixelReader pixelReader = source.getPixelReader(); - WritableImage newImage = new WritableImage(imageWidth, imageHeight); - PixelWriter pixelWriter = newImage.getPixelWriter(); - boolean excluded = scope.isColorExcluded(); - if (excluded) { - for (int y = 0; y < imageHeight; y++) { - for (int x = 0; x < imageWidth; x++) { - Color color = pixelReader.getColor(x, y); - Color newColor = FxmlColorTools.posterizingColor(color, size); - pixelWriter.setColor(x, y, newColor); - } - } - } else { - pixelWriter.setPixels(0, 0, imageWidth, imageHeight, pixelReader, 0, 0); - } - - boolean[][] visited = new boolean[imageHeight][imageWidth]; - Queue queue = new LinkedList<>(); - - for (IntPoint point : points) { - Color startColor = pixelReader.getColor(point.getX(), point.getY()); - queue.add(point); - while (!queue.isEmpty()) { - IntPoint p = queue.remove(); - int x = p.getX(), y = p.getY(); - if (x < 0 || x >= imageWidth || y < 0 || y >= imageHeight - || visited[y][x]) { - continue; - } - visited[y][x] = true; - Color color = pixelReader.getColor(x, y); - if (FxmlColorTools.isColorMatch(color, startColor, distance)) { - if (excluded) { - pixelWriter.setColor(x, y, color); - } else { - Color newColor = FxmlColorTools.posterizingColor(color, size); - pixelWriter.setColor(x, y, newColor); - } - queue.add(new IntPoint(x + 1, y)); - queue.add(new IntPoint(x - 1, y)); - queue.add(new IntPoint(x, y + 1)); - queue.add(new IntPoint(x, y - 1)); - } - } - } - return newImage; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - } - - public static Image thresholdingImage(Image image, - int threshold, int smallValue, int bigValue, ImageScope scope) { - if (image == null || threshold < 0 || threshold > 255 - || smallValue < 0 || smallValue > 255 || bigValue < 0 || bigValue > 255) { - return image; - } - if (scope == null || scope.getScopeType() == ImageScope.ScopeType.All) { - return FxmlEffectTools.thresholdingImage(image, threshold, smallValue, bigValue); - } else if (scope.getScopeType() == ImageScope.ScopeType.Matting) { - return FxmlEffectTools.thresholdingByMatting(image, threshold, smallValue, bigValue, scope); - } else { - return FxmlEffectTools.thresholdingByScope(image, threshold, smallValue, bigValue, scope); - } - } - - public static Image thresholdingImage(Image image, int threshold, int smallValue, int bigValue) { - if (image == null || threshold < 0 || threshold > 255 - || smallValue < 0 || smallValue > 255 || bigValue < 0 || bigValue > 255) { - return image; - } - int imageWidth = (int) image.getWidth(); - int imageHeight = (int) image.getHeight(); - PixelReader pixelReader = image.getPixelReader(); - WritableImage newImage = new WritableImage(imageWidth, imageHeight); - PixelWriter pixelWriter = newImage.getPixelWriter(); - - for (int y = 0; y < image.getHeight(); y++) { - for (int x = 0; x < image.getWidth(); x++) { - Color color = pixelReader.getColor(x, y); - Color newColor = FxmlColorTools.thresholdingColor(color, - threshold, smallValue, bigValue); - pixelWriter.setColor(x, y, newColor); - } - } - return newImage; - } - - public static Image thresholdingByScope(Image image, - int threshold, int smallValue, int bigValue, ImageScope scope) { - if (image == null || threshold < 0 || threshold > 255 - || smallValue < 0 || smallValue > 255 || bigValue < 0 || bigValue > 255 - || scope == null) { - return image; - } - int imageWidth = (int) image.getWidth(); - int imageHeight = (int) image.getHeight(); - PixelReader pixelReader = image.getPixelReader(); - WritableImage newImage = new WritableImage(imageWidth, imageHeight); - PixelWriter pixelWriter = newImage.getPixelWriter(); - - for (int y = 0; y < image.getHeight(); y++) { - for (int x = 0; x < image.getWidth(); x++) { - Color color = pixelReader.getColor(x, y); - if (scope.inScope(x, y, color)) { - Color newColor = FxmlColorTools.thresholdingColor(color, - threshold, smallValue, bigValue); - pixelWriter.setColor(x, y, newColor); - } else { - pixelWriter.setColor(x, y, color); - } - } - } - return newImage; - } - - public static Image thresholdingByMatting(Image source, - int threshold, int smallValue, int bigValue, ImageScope scope) { - try { - if (source == null || threshold < 0 || threshold > 255 - || smallValue < 0 || smallValue > 255 || bigValue < 0 || bigValue > 255) { - return source; - } - List points = scope.getPoints(); - double distance = scope.getColorDistance(); - if (points == null || points.isEmpty() - || distance < 0 || distance > 1) { - return source; - } - - int imageWidth = (int) source.getWidth(); - int imageHeight = (int) source.getHeight(); - PixelReader pixelReader = source.getPixelReader(); - WritableImage newImage = new WritableImage(imageWidth, imageHeight); - PixelWriter pixelWriter = newImage.getPixelWriter(); - boolean excluded = scope.isColorExcluded(); - if (excluded) { - for (int y = 0; y < imageHeight; y++) { - for (int x = 0; x < imageWidth; x++) { - Color color = pixelReader.getColor(x, y); - Color newColor = FxmlColorTools.thresholdingColor(color, - threshold, smallValue, bigValue); - pixelWriter.setColor(x, y, newColor); - } - } - } else { - pixelWriter.setPixels(0, 0, imageWidth, imageHeight, pixelReader, 0, 0); - } - - boolean[][] visited = new boolean[imageHeight][imageWidth]; - Queue queue = new LinkedList<>(); - - for (IntPoint point : points) { - Color startColor = pixelReader.getColor(point.getX(), point.getY()); - queue.add(point); - while (!queue.isEmpty()) { - IntPoint p = queue.remove(); - int x = p.getX(), y = p.getY(); - if (x < 0 || x >= imageWidth || y < 0 || y >= imageHeight - || visited[y][x]) { - continue; - } - visited[y][x] = true; - Color color = pixelReader.getColor(x, y); - if (FxmlColorTools.isColorMatch(color, startColor, distance)) { - if (excluded) { - pixelWriter.setColor(x, y, color); - } else { - Color newColor = FxmlColorTools.thresholdingColor(color, - threshold, smallValue, bigValue); - pixelWriter.setColor(x, y, newColor); - } - queue.add(new IntPoint(x + 1, y)); - queue.add(new IntPoint(x - 1, y)); - queue.add(new IntPoint(x, y + 1)); - queue.add(new IntPoint(x, y - 1)); - } - } - } - return newImage; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - } - - public static Image makeColor(Image source, EffectsOperationType type, - double value, ImageScope scope) { - if (scope.getScopeType() == ImageScope.ScopeType.Matting) { - return makeColorByMatting(source, type, value, scope); - } else { - return makeColorByScope(source, type, value, scope); - } - } - - public static Image makeColorByScope(Image source, EffectsOperationType type, - double value, ImageScope scope) { - PixelReader pixelReader = source.getPixelReader(); - WritableImage newImage = new WritableImage((int) source.getWidth(), (int) source.getHeight()); - PixelWriter pixelWriter = newImage.getPixelWriter(); - - for (int y = 0; y < source.getHeight(); y++) { - for (int x = 0; x < source.getWidth(); x++) { - Color color = pixelReader.getColor(x, y); - if (color == Color.TRANSPARENT) { - pixelWriter.setColor(x, y, color); - continue; - } - if (scope == null || scope.inScope(x, y, color)) { - Color newColor = makeColor(color, type, value); - pixelWriter.setColor(x, y, newColor); - } else { - pixelWriter.setColor(x, y, color); - } - } - } - return newImage; - } - - public static Image makeColorByMatting(Image source, EffectsOperationType type, - double value, ImageScope scope) { - try { - if (source == null) { - return source; - } - List points = scope.getPoints(); - double distance = scope.getColorDistance(); - if (points == null || points.isEmpty() - || distance < 0 || distance > 1) { - return source; - } - int width = (int) source.getWidth(); - int height = (int) source.getHeight(); - PixelReader pixelReader = source.getPixelReader(); - WritableImage newImage = new WritableImage(width, height); - PixelWriter pixelWriter = newImage.getPixelWriter(); - boolean excluded = scope.isColorExcluded(); - if (excluded) { - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - Color color = pixelReader.getColor(x, y); - Color newColor = makeColor(color, type, value); - pixelWriter.setColor(x, y, newColor); - } - } - } else { - pixelWriter.setPixels(0, 0, width, height, pixelReader, 0, 0); - } - - boolean[][] visited = new boolean[height][width]; - Queue queue = new LinkedList<>(); - - for (mara.mybox.objects.IntPoint point : points) { - Color startColor = pixelReader.getColor(point.getX(), point.getY()); - queue.add(point); - while (!queue.isEmpty()) { - mara.mybox.objects.IntPoint p = queue.remove(); - int x = p.getX(), y = p.getY(); - if (x < 0 || x >= width || y < 0 || y >= height - || visited[y][x]) { - continue; - } - visited[y][x] = true; - Color color = pixelReader.getColor(x, y); - if (FxmlColorTools.isColorMatch(color, startColor, distance)) { - if (excluded) { - pixelWriter.setColor(x, y, color); - } else { - Color newColor = makeColor(color, type, value); - pixelWriter.setColor(x, y, newColor); - } - queue.add(new mara.mybox.objects.IntPoint(x + 1, y)); - queue.add(new mara.mybox.objects.IntPoint(x - 1, y)); - queue.add(new mara.mybox.objects.IntPoint(x, y + 1)); - queue.add(new mara.mybox.objects.IntPoint(x, y - 1)); - } - } - } - - return newImage; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - - } - - public static Color makeColor(Color color, EffectsOperationType type, double value) { - Color newColor = color; - switch (type) { - case Gray: - newColor = color.grayscale(); // JDK internal: 0.21 * red + 0.71 * green + 0.07 * blue - break; - case BlackOrWhite: - double gray = 21.26 * color.getRed() + 71.52 * color.getGreen() + 7.22 * color.getBlue(); - if (gray < value) { - newColor = Color.BLACK; - } else { - newColor = Color.WHITE; - } - break; - case Sepia: - newColor = FxmlColorTools.pixel2Sepia(color, value); - break; - default: - break; - } - return newColor; - - } - -} diff --git a/MyBox/src/main/java/mara/mybox/fxml/FxmlFilterTools.java b/MyBox/src/main/java/mara/mybox/fxml/FxmlFilterTools.java deleted file mode 100644 index ea776c2f6..000000000 --- a/MyBox/src/main/java/mara/mybox/fxml/FxmlFilterTools.java +++ /dev/null @@ -1,181 +0,0 @@ -package mara.mybox.fxml; - -import java.util.LinkedList; -import java.util.List; -import java.util.Queue; -import javafx.scene.image.Image; -import javafx.scene.image.PixelReader; -import javafx.scene.image.PixelWriter; -import javafx.scene.image.WritableImage; -import javafx.scene.paint.Color; -import mara.mybox.objects.ImageScope; -import mara.mybox.objects.IntPoint; -import static mara.mybox.objects.AppVaribles.logger; - - -/** - * @Author Mara - * @CreateDate 2018-11-10 19:26:55 - * @Version 1.0 - * @Description - * @License Apache License Version 2.0 - */ -public class FxmlFilterTools { - - - - public enum FiltersOperationType { - Gray, - Invert, - BlackOrWhite, - Red, - Green, - Blue, - RedInvert, - GreenInvert, - BlueInvert, - Sepia, - Yellow, - Cyan, - Magenta - } - - public static Image filterColorByScope(Image source, FiltersOperationType type, - double value, ImageScope scope) { - PixelReader pixelReader = source.getPixelReader(); - WritableImage newImage = new WritableImage((int) source.getWidth(), (int) source.getHeight()); - PixelWriter pixelWriter = newImage.getPixelWriter(); - - for (int y = 0; y < source.getHeight(); y++) { - for (int x = 0; x < source.getWidth(); x++) { - Color color = pixelReader.getColor(x, y); - if (color == Color.TRANSPARENT) { - pixelWriter.setColor(x, y, color); - continue; - } - if (scope == null || scope.inScope(x, y, color)) { - Color newColor = filterColor(color, type, value); - pixelWriter.setColor(x, y, newColor); - } else { - pixelWriter.setColor(x, y, color); - } - } - } - return newImage; - } - - public static Image filterColorByMatting(Image source, FiltersOperationType type, double value, - List points, double distance) { - try { - if (source == null - || points == null || points.isEmpty() - || distance < 0 || distance > 1) { - return source; - } - int width = (int) source.getWidth(); - int height = (int) source.getHeight(); - PixelReader pixelReader = source.getPixelReader(); - WritableImage newImage = new WritableImage(width, height); - PixelWriter pixelWriter = newImage.getPixelWriter(); - pixelWriter.setPixels(0, 0, width, height, pixelReader, 0, 0); - - boolean[][] visited = new boolean[height][width]; - Queue queue = new LinkedList<>(); - - for (mara.mybox.objects.IntPoint point : points) { - Color startColor = pixelReader.getColor(point.getX(), point.getY()); - queue.add(point); - while (!queue.isEmpty()) { - mara.mybox.objects.IntPoint p = queue.remove(); - int x = p.getX(), y = p.getY(); - if (x < 0 || x >= width || y < 0 || y >= height - || visited[y][x]) { - continue; - } - visited[y][x] = true; - Color color = pixelReader.getColor(x, y); - if (FxmlColorTools.isColorMatch(color, startColor, distance)) { - Color newColor = filterColor(color, type, value); - pixelWriter.setColor(x, y, newColor); - queue.add(new mara.mybox.objects.IntPoint(x + 1, y)); - queue.add(new mara.mybox.objects.IntPoint(x - 1, y)); - queue.add(new mara.mybox.objects.IntPoint(x, y + 1)); - queue.add(new mara.mybox.objects.IntPoint(x, y - 1)); - } - } - } - - return newImage; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - - } - - public static Color filterColor(Color color, FiltersOperationType type, double value) { - Color newColor = color; - switch (type) { - case Gray: - newColor = color.grayscale(); // JDK internal: 0.21 * red + 0.71 * green + 0.07 * blue - break; - case Invert: - newColor = color.invert(); - break; - case BlackOrWhite: - double gray = 21.26 * color.getRed() + 71.52 * color.getGreen() + 7.22 * color.getBlue(); - if (gray < value) { - newColor = Color.BLACK; - } else { - newColor = Color.WHITE; - } - break; - case Red: - newColor = new Color(color.getRed(), 0, 0, color.getOpacity()); - break; - case Green: - newColor = new Color(0, color.getGreen(), 0, color.getOpacity()); - break; - case Blue: - newColor = new Color(0, 0, color.getBlue(), color.getOpacity()); - break; - case Yellow: - newColor = new Color(color.getRed(), color.getGreen(), 0, color.getOpacity()); - break; - case Cyan: - newColor = new Color(0, color.getGreen(), color.getBlue(), color.getOpacity()); - break; - case Magenta: - newColor = new Color(color.getRed(), 0, color.getBlue(), color.getOpacity()); - break; - case RedInvert: - newColor = new Color(1.0 - color.getRed(), color.getGreen(), color.getBlue(), color.getOpacity()); - break; - case GreenInvert: - newColor = new Color(color.getRed(), 1.0 - color.getGreen(), color.getBlue(), color.getOpacity()); - break; - case BlueInvert: - newColor = new Color(color.getRed(), color.getGreen(), 1.0 - color.getBlue(), color.getOpacity()); - break; - case Sepia: - newColor = pixel2Sepia(color, value); - break; - default: - break; - } - return newColor; - - } - - public static Color pixel2Sepia(Color color, double sepiaIntensity) { - double sepiaDepth = 20; - double gray = color.grayscale().getRed() * 255; - double r = gray, g = gray, b = gray; - r = Math.min(r + (sepiaDepth * 2), 255); - g = Math.min(g + sepiaDepth, 255); - b = Math.min(Math.max(b - sepiaIntensity, 0), 255); - Color newColor = new Color(r / 255.0f, g / 255.0f, b / 255.0f, color.getOpacity()); - return newColor; - } - -} diff --git a/MyBox/src/main/java/mara/mybox/fxml/FxmlReplaceColorTools.java b/MyBox/src/main/java/mara/mybox/fxml/FxmlReplaceColorTools.java deleted file mode 100644 index 3b8b8b77c..000000000 --- a/MyBox/src/main/java/mara/mybox/fxml/FxmlReplaceColorTools.java +++ /dev/null @@ -1,128 +0,0 @@ -package mara.mybox.fxml; - -import java.util.LinkedList; -import java.util.List; -import java.util.Queue; -import javafx.scene.image.Image; -import javafx.scene.image.PixelReader; -import javafx.scene.image.PixelWriter; -import javafx.scene.image.WritableImage; -import javafx.scene.paint.Color; -import mara.mybox.objects.IntCircle; -import mara.mybox.objects.ImageScope; -import mara.mybox.objects.IntPoint; -import mara.mybox.objects.IntRectangle; -import static mara.mybox.objects.AppVaribles.logger; - - -/** - * @Author Mara - * @CreateDate 2018-11-10 19:51:22 - * @Version 1.0 - * @Description - * @License Apache License Version 2.0 - */ -public class FxmlReplaceColorTools { - - - - public static Image replaceColors(Image image, Color newColor, ImageScope scope) { - PixelReader pixelReader = image.getPixelReader(); - WritableImage newImage = new WritableImage((int) image.getWidth(), (int) image.getHeight()); - PixelWriter pixelWriter = newImage.getPixelWriter(); - - for (int y = 0; y < image.getHeight(); y++) { - for (int x = 0; x < image.getWidth(); x++) { - Color color = pixelReader.getColor(x, y); - if (scope.inScope(x, y, color)) { - pixelWriter.setColor(x, y, newColor); - } else { - pixelWriter.setColor(x, y, color); - } - } - } - return newImage; - } - - public static Image replaceColorsRectangle(Image image, Color newColor, IntRectangle rect) { - PixelReader pixelReader = image.getPixelReader(); - WritableImage newImage = new WritableImage((int) image.getWidth(), (int) image.getHeight()); - PixelWriter pixelWriter = newImage.getPixelWriter(); - - for (int y = 0; y < image.getHeight(); y++) { - for (int x = 0; x < image.getWidth(); x++) { - if (rect.include(x, y)) { - pixelWriter.setColor(x, y, newColor); - } else { - pixelWriter.setColor(x, y, pixelReader.getColor(x, y)); - } - } - } - return newImage; - } - - public static Image replaceColorsCircle(Image image, Color newColor, IntCircle circle) { - PixelReader pixelReader = image.getPixelReader(); - WritableImage newImage = new WritableImage((int) image.getWidth(), (int) image.getHeight()); - PixelWriter pixelWriter = newImage.getPixelWriter(); - - for (int y = 0; y < image.getHeight(); y++) { - for (int x = 0; x < image.getWidth(); x++) { - if (circle.include(x, y)) { - pixelWriter.setColor(x, y, newColor); - } else { - pixelWriter.setColor(x, y, pixelReader.getColor(x, y)); - } - } - } - return newImage; - } - - public static Image replaceColorsMatting(Image source, Color newColor, - List points, double distance) { - try { - if (source == null - || points == null || points.isEmpty() - || distance < 0 || distance > 1) { - return source; - } - int width = (int) source.getWidth(); - int height = (int) source.getHeight(); - PixelReader pixelReader = source.getPixelReader(); - WritableImage newImage = new WritableImage(width, height); - PixelWriter pixelWriter = newImage.getPixelWriter(); - pixelWriter.setPixels(0, 0, width, height, pixelReader, 0, 0); - - boolean[][] visited = new boolean[height][width]; - Queue queue = new LinkedList<>(); - for (IntPoint point : points) { - Color startColor = pixelReader.getColor(point.getX(), point.getY()); - queue.add(point); - while (!queue.isEmpty()) { - IntPoint p = queue.remove(); - int x = p.getX(), y = p.getY(); - if (x < 0 || x >= width || y < 0 || y >= height - || visited[y][x]) { - continue; - } - visited[y][x] = true; - Color pixelColor = pixelReader.getColor(x, y); - if (FxmlColorTools.isColorMatch(pixelColor, startColor, distance)) { - pixelWriter.setColor(x, y, newColor); - queue.add(new IntPoint(x + 1, y)); - queue.add(new IntPoint(x - 1, y)); - queue.add(new IntPoint(x, y + 1)); - queue.add(new IntPoint(x, y - 1)); - } - } - } - - return newImage; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - - } - -} diff --git a/MyBox/src/main/java/mara/mybox/fxml/FxmlScopeTools.java b/MyBox/src/main/java/mara/mybox/fxml/FxmlScopeTools.java deleted file mode 100644 index cf5fb15f4..000000000 --- a/MyBox/src/main/java/mara/mybox/fxml/FxmlScopeTools.java +++ /dev/null @@ -1,154 +0,0 @@ -package mara.mybox.fxml; - -import java.awt.image.BufferedImage; -import java.util.LinkedList; -import java.util.List; -import java.util.Queue; -import javafx.embed.swing.SwingFXUtils; -import javafx.scene.image.Image; -import javafx.scene.image.PixelReader; -import javafx.scene.image.PixelWriter; -import javafx.scene.image.WritableImage; -import javafx.scene.paint.Color; -import static mara.mybox.fxml.FxmlColorTools.isColorMatch; -import mara.mybox.image.ImageScopeTools; -import mara.mybox.objects.IntCircle; -import mara.mybox.objects.ImageScope; -import mara.mybox.objects.IntPoint; -import mara.mybox.objects.IntRectangle; -import static mara.mybox.objects.AppVaribles.logger; - - -/** - * @Author Mara - * @CreateDate 2018-11-10 19:44:49 - * @Version 1.0 - * @Description - * @License Apache License Version 2.0 - */ -public class FxmlScopeTools { - - - - public static Image indicateRectangle(Image image, - Color color, int lineWidth, IntRectangle rect) { - BufferedImage source = SwingFXUtils.fromFXImage(image, null); - BufferedImage target = ImageScopeTools.indicateRectangle(source, - FxmlImageTools.colorConvert(color), lineWidth, rect); - Image newImage = SwingFXUtils.toFXImage(target, null); - return newImage; - } - - public static Image indicateCircle(Image image, - Color color, int lineWidth, IntCircle circle) { - BufferedImage source = SwingFXUtils.fromFXImage(image, null); - BufferedImage target = ImageScopeTools.indicateCircle(source, - FxmlImageTools.colorConvert(color), lineWidth, circle); - Image newImage = SwingFXUtils.toFXImage(target, null); - return newImage; - } - - public static Image scopeImage(Image image, ImageScope scope) { - if (scope.getScopeType() == ImageScope.ScopeType.All) { - return image; - } - PixelReader pixelReader = image.getPixelReader(); - WritableImage newImage = new WritableImage((int) image.getWidth(), (int) image.getHeight()); - PixelWriter pixelWriter = newImage.getPixelWriter(); - - double opacity = scope.getOpacity(); - for (int y = 0; y < image.getHeight(); y++) { - for (int x = 0; x < image.getWidth(); x++) { - Color color = pixelReader.getColor(x, y); - if (color == Color.TRANSPARENT) { - pixelWriter.setColor(x, y, color); - continue; - } - if (!scope.inScope(x, y, color)) { - Color opacityColor = new Color(color.getRed(), color.getGreen(), color.getBlue(), opacity); - pixelWriter.setColor(x, y, opacityColor); - } else { - pixelWriter.setColor(x, y, color); - } - } - } - - return newImage; - } - - // https://en.wikipedia.org/wiki/Flood_fill - // https://www.codeproject.com/Articles/6017/QuickFill-An-Efficient-Flood-Fill-Algorithm - public static Image scopeMatting(Image source, ImageScope scope) { - try { - if (scope == null) { - return source; - } - int width = (int) source.getWidth(); - int height = (int) source.getHeight(); - PixelReader pixelReader = source.getPixelReader(); - WritableImage newImage = new WritableImage(width, height); - PixelWriter pixelWriter = newImage.getPixelWriter(); - double opacity = scope.getOpacity(); - - boolean excluded = scope.isColorExcluded(); - if (excluded) { - pixelWriter.setPixels(0, 0, width, height, pixelReader, 0, 0); - } else { - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - Color color = pixelReader.getColor(x, y); - if (color == Color.TRANSPARENT) { - pixelWriter.setColor(x, y, color); - continue; - } - Color newColor = new Color(color.getRed(), color.getGreen(), color.getBlue(), opacity); - pixelWriter.setColor(x, y, newColor); - } - } - } - if (scope.getPoints() == null || scope.getPoints().isEmpty()) { - return newImage; - } - - boolean[][] visited = new boolean[height][width]; - Queue queue = new LinkedList<>(); - List points = scope.getPoints(); - double distance = scope.getColorDistance(); - - for (IntPoint point : points) { - Color startColor = pixelReader.getColor(point.getX(), point.getY()); - queue.add(point); - while (!queue.isEmpty()) { - mara.mybox.objects.IntPoint p = queue.remove(); - int x = p.getX(), y = p.getY(); - if (x < 0 || x >= width || y < 0 || y >= height - || visited[y][x]) { - continue; - } - visited[y][x] = true; - Color pixelColor = pixelReader.getColor(x, y); - if (isColorMatch(pixelColor, startColor, distance)) { - if (excluded) { - Color newColor = new Color(pixelColor.getRed(), pixelColor.getGreen(), pixelColor.getBlue(), opacity); - pixelWriter.setColor(x, y, newColor); - } else { - pixelWriter.setColor(x, y, pixelColor); - } - queue.add(new mara.mybox.objects.IntPoint(x + 1, y)); - queue.add(new mara.mybox.objects.IntPoint(x - 1, y)); - queue.add(new mara.mybox.objects.IntPoint(x, y + 1)); - queue.add(new mara.mybox.objects.IntPoint(x, y - 1)); - } - - } - } - - return newImage; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - - } - -} diff --git a/MyBox/src/main/java/mara/mybox/controller/OpenFile.java b/MyBox/src/main/java/mara/mybox/fxml/FxmlStage.java similarity index 53% rename from MyBox/src/main/java/mara/mybox/controller/OpenFile.java rename to MyBox/src/main/java/mara/mybox/fxml/FxmlStage.java index 20f03677c..e4272628f 100644 --- a/MyBox/src/main/java/mara/mybox/controller/OpenFile.java +++ b/MyBox/src/main/java/mara/mybox/fxml/FxmlStage.java @@ -1,4 +1,4 @@ -package mara.mybox.controller; +package mara.mybox.fxml; import java.awt.Desktop; import java.io.File; @@ -6,14 +6,29 @@ import javafx.event.EventHandler; import javafx.fxml.FXMLLoader; import javafx.scene.Scene; +import javafx.scene.control.Alert; +import javafx.scene.image.Image; import javafx.scene.layout.Pane; +import javafx.scene.layout.Region; import javafx.stage.Modality; import javafx.stage.Stage; import javafx.stage.StageStyle; import javafx.stage.WindowEvent; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.CommonValues; +import mara.mybox.controller.BaseController; +import mara.mybox.controller.BytesEditerController; +import mara.mybox.controller.HtmlEditorController; +import mara.mybox.controller.ImageInformationController; +import mara.mybox.controller.ImageManufactureController; +import mara.mybox.controller.ImageMetaDataController; +import mara.mybox.controller.ImageStatisticController; +import mara.mybox.controller.ImageViewerController; +import mara.mybox.controller.ImagesBrowserController; +import mara.mybox.controller.PdfViewController; +import mara.mybox.controller.TextEditerController; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.value.CommonValues; +import mara.mybox.data.ImageInformation; import mara.mybox.tools.FileTools; /** @@ -23,17 +38,17 @@ * @Description * @License Apache License Version 2.0 */ -public class OpenFile { +public class FxmlStage { public static BaseController openNewStage(Class theClass, Stage myStage, String newFxml, String title, boolean isOwned, boolean monitorClosing) { try { FXMLLoader fxmlLoader = new FXMLLoader(theClass.getResource(newFxml), AppVaribles.CurrentBundle); Pane pane = fxmlLoader.load(); + pane.getStylesheets().add(theClass.getResource(AppVaribles.getStyle()).toExternalForm()); final BaseController controller = fxmlLoader.getController(); Stage stage = new Stage(); controller.setMyStage(stage); - Scene scene = new Scene(pane); stage.initModality(Modality.NONE); if (isOwned) { @@ -47,6 +62,7 @@ public static BaseController openNewStage(Class theClass, Stage myStage, stage.setTitle(title); } controller.setBaseTitle(stage.getTitle()); + controller.setMyStage(stage); stage.getIcons().add(CommonValues.AppIcon); stage.setScene(scene); if (monitorClosing) { @@ -60,7 +76,7 @@ public void handle(WindowEvent event) { }); } stage.show(); - controller.setMyStage(stage); + pane.requestFocus(); return controller; } catch (Exception e) { logger.error(e.toString()); @@ -71,21 +87,17 @@ public void handle(WindowEvent event) { public static BaseController openStage(Class theClass, Stage stage, String newFxml, String title) { try { + FXMLLoader fxmlLoader = new FXMLLoader(theClass.getResource(newFxml), AppVaribles.CurrentBundle); + Pane pane = fxmlLoader.load(); + pane.getStylesheets().add(theClass.getResource(AppVaribles.getStyle()).toExternalForm()); + final BaseController controller = (BaseController) fxmlLoader.getController(); if (stage == null) { stage = new Stage(); stage.initModality(Modality.NONE); stage.initStyle(StageStyle.DECORATED); stage.initOwner(null); } - FXMLLoader fxmlLoader = new FXMLLoader(theClass.getResource(newFxml), AppVaribles.CurrentBundle); - Pane pane = fxmlLoader.load(); - final BaseController controller = (BaseController) fxmlLoader.getController(); - controller.setMyStage(stage); - if (title == null) { - controller.setBaseTitle(AppVaribles.getMessage("AppTitle")); - } else { - controller.setBaseTitle(title); - } + stage.getIcons().add(CommonValues.AppIcon); stage.setOnCloseRequest(new EventHandler() { @Override public void handle(WindowEvent event) { @@ -94,16 +106,19 @@ public void handle(WindowEvent event) { } } }); + controller.setMyStage(stage); + if (title == null) { + controller.setBaseTitle(AppVaribles.getMessage("AppTitle")); + } else { + controller.setBaseTitle(title); + } - stage.getIcons().add(CommonValues.AppIcon); stage.setTitle(controller.getBaseTitle()); stage.setScene(new Scene(pane)); stage.show(); - - pane.getStylesheets().add(theClass.getResource(AppVaribles.getStyle()).toExternalForm()); + pane.requestFocus(); return controller; - } catch (Exception e) { logger.error(e.toString()); return null; @@ -154,6 +169,48 @@ public static ImageManufactureController openImageManufacture(Class theClass, St } } + public static ImageManufactureController openImageManufacture(Class theClass, Stage stage, + File file, Image image, ImageInformation imageInfo) { + try { + final ImageManufactureController controller + = (ImageManufactureController) openStage(theClass, stage, + CommonValues.ImageManufactureFileFxml, AppVaribles.getMessage("ImageManufacture")); + controller.loadImage(file, image, imageInfo); + return controller; + } catch (Exception e) { + logger.error(e.toString()); + return null; + } + } + + public static ImageManufactureController openImageManufacture(Class theClass, Stage stage, + ImageInformation imageInfo) { + try { + final ImageManufactureController controller + = (ImageManufactureController) openStage(theClass, stage, + CommonValues.ImageManufactureFileFxml, AppVaribles.getMessage("ImageManufacture")); + controller.loadImage(imageInfo); + return controller; + } catch (Exception e) { + logger.error(e.toString()); + return null; + } + } + + public static ImageManufactureController openImageManufacture(Class theClass, Stage stage, + Image image) { + try { + final ImageManufactureController controller + = (ImageManufactureController) openStage(theClass, stage, + CommonValues.ImageManufactureFileFxml, AppVaribles.getMessage("ImageManufacture")); + controller.loadImage(image); + return controller; + } catch (Exception e) { + logger.error(e.toString()); + return null; + } + } + public static ImageViewerController openImageViewer(Class theClass, Stage stage) { try { final ImageViewerController controller @@ -179,37 +236,11 @@ public static ImageViewerController openImageViewer(Class theClass, Stage stage, } } - public static ImagesViewerController openImagesViewer(Class theClass, Stage stage) { + public static ImagesBrowserController openImagesBrowser(Class theClass, Stage stage) { try { - if (stage == null) { - stage = new Stage(); - stage.initModality(Modality.NONE); - stage.initStyle(StageStyle.DECORATED); - stage.initOwner(null); - } - FXMLLoader fxmlLoader = new FXMLLoader(theClass.getResource(CommonValues.ImagesViewerFxml), AppVaribles.CurrentBundle); - Pane pane = fxmlLoader.load(); - final ImagesViewerController controller = (ImagesViewerController) fxmlLoader.getController(); - controller.setMyStage(stage); - controller.setBaseTitle(AppVaribles.getMessage("MultipleImagesViewer")); - stage.setOnCloseRequest(new EventHandler() { - @Override - public void handle(WindowEvent event) { - if (!controller.stageClosing()) { - event.consume(); - } - } - }); - - stage.getIcons().add(CommonValues.AppIcon); - stage.setTitle(controller.getBaseTitle()); - stage.setScene(new Scene(pane)); - stage.show(); - - pane.getStylesheets().add(theClass.getResource(AppVaribles.getStyle()).toExternalForm()); - + final ImagesBrowserController controller = (ImagesBrowserController) openStage(theClass, stage, + CommonValues.ImagesBrowserFxml, AppVaribles.getMessage("ImagesBrowser")); return controller; - } catch (Exception e) { logger.error(e.toString()); return null; @@ -229,58 +260,150 @@ public static TextEditerController openTextEditer(Class theClass, Stage stage, F } } - public static Stage openBytesEditer(Class theClass, Stage stage, File file) { + public static BytesEditerController openBytesEditer(Class theClass, Stage stage, File file) { try { final BytesEditerController controller = (BytesEditerController) openStage(theClass, stage, CommonValues.BytesEditerFxml, AppVaribles.getMessage("BytesEditer")); controller.openFile(file); - return stage; + return controller; + } catch (Exception e) { + logger.error(e.toString()); + return null; + } + } + + public static ImageInformationController openImageInformation(Class theClass, Stage stage, ImageInformation info) { + try { + final ImageInformationController controller = (ImageInformationController) openStage(theClass, stage, + CommonValues.ImageInformationFxml, AppVaribles.getMessage("ImageInformation")); + controller.loadInformation(info); + return controller; + } catch (Exception e) { + logger.error(e.toString()); + return null; + } + } + + public static ImageMetaDataController openImageMetaData(Class theClass, Stage stage, ImageInformation info) { + try { + final ImageMetaDataController controller = (ImageMetaDataController) openStage(theClass, stage, + CommonValues.ImageMetaDataFxml, AppVaribles.getMessage("ImageInformation")); + controller.loadData(info); + return controller; } catch (Exception e) { logger.error(e.toString()); return null; } } - public static boolean openTarget(Class theClass, Stage stage, String filename) { + public static ImageStatisticController openImageStatistic(Class theClass, Stage stage, ImageInformation info) { + try { + final ImageStatisticController controller = (ImageStatisticController) openStage(theClass, stage, + CommonValues.ImageStatisticFxml, AppVaribles.getMessage("ImageStatistic")); + controller.loadImage(info); + return controller; + } catch (Exception e) { + logger.error(e.toString()); + return null; + } + } + + public static ImageStatisticController openImageStatistic(Class theClass, Stage stage, Image image) { + try { + final ImageStatisticController controller = (ImageStatisticController) openStage(theClass, stage, + CommonValues.ImageStatisticFxml, AppVaribles.getMessage("ImageStatistic")); + controller.loadImage(image); + return controller; + } catch (Exception e) { + logger.error(e.toString()); + return null; + } + } + + public static BaseController openTarget(Class theClass, Stage stage, + String filename) { + return openTarget(theClass, stage, filename, true); + } + + public static BaseController openTarget(Class theClass, Stage stage, + String filename, boolean mustOpen) { + BaseController controller = null; if (filename == null) { - return false; + return controller; } File file = new File(filename); if (!file.exists()) { - return false; + return controller; } if (file.isDirectory()) { try { Desktop.getDesktop().browse(file.toURI()); - return true; } catch (Exception e) { - return false; + } + return controller; } String suffix = FileTools.getFileSuffix(file.getAbsolutePath()).toLowerCase(); if (CommonValues.SupportedImages.contains(suffix)) { - openImageManufacture(theClass, stage, file); + controller = openImageViewer(theClass, stage, file); } else if ("html".equals(suffix) || "htm".equals(suffix)) { - OpenFile.openHtmlEditor(theClass, stage, file); + controller = openHtmlEditor(theClass, stage, file); } else if (Arrays.asList(CommonValues.TextFileSuffix).contains(suffix)) { - OpenFile.openTextEditer(theClass, stage, file); + controller = openTextEditer(theClass, stage, file); } else if ("pdf".equals(suffix)) { - OpenFile.openPdfViewer(theClass, stage, file); + controller = openPdfViewer(theClass, stage, file); - } else { + } else if (mustOpen) { try { Desktop.getDesktop().browse(file.toURI()); } catch (Exception e) { - return false; } } - return true; + return controller; + } + public static void alertError(Stage myStage, String information) { + try { + Alert alert = new Alert(Alert.AlertType.ERROR); + alert.setTitle(myStage.getTitle()); + alert.setHeaderText(null); + alert.setContentText(information); + alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); + alert.showAndWait(); + } catch (Exception e) { + logger.error(e.toString()); + } + } + + public static void alertWarning(Stage myStage, String information) { + try { + Alert alert = new Alert(Alert.AlertType.WARNING); + alert.setTitle(myStage.getTitle()); + alert.setHeaderText(null); + alert.setContentText(information); + alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); + alert.showAndWait(); + } catch (Exception e) { + logger.error(e.toString()); + } + } + + public static void alertInformation(Stage myStage, String information) { + try { + Alert alert = new Alert(Alert.AlertType.INFORMATION); + alert.setTitle(myStage.getTitle()); + alert.setHeaderText(null); + alert.setContentText(information); + alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE); + alert.showAndWait(); + } catch (Exception e) { + logger.error(e.toString()); + } } } diff --git a/MyBox/src/main/java/mara/mybox/fxml/FxmlTools.java b/MyBox/src/main/java/mara/mybox/fxml/FxmlTools.java index 713a6fb06..2ef3b77b5 100644 --- a/MyBox/src/main/java/mara/mybox/fxml/FxmlTools.java +++ b/MyBox/src/main/java/mara/mybox/fxml/FxmlTools.java @@ -22,12 +22,12 @@ import javafx.scene.input.MouseEvent; import javax.sound.sampled.Clip; import javax.sound.sampled.FloatControl; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.CommonValues; +import mara.mybox.value.AppVaribles; +import mara.mybox.value.CommonValues; import mara.mybox.tools.SoundTools; -import static mara.mybox.objects.CommonValues.UserFilePath; import static mara.mybox.tools.FileTools.getFileSuffix; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.logger; +import static mara.mybox.value.CommonValues.AppDataRoot; /** * @Author Mara @@ -202,7 +202,7 @@ public void changed(ObservableValue observable, } public static void setPositiveValidation(final TextField input) { - setNonnegativeValidation(input, Integer.MAX_VALUE); + setPositiveValidation(input, Integer.MAX_VALUE); } public static void setPositiveValidation(final TextField input, final int max) { @@ -303,7 +303,7 @@ public static File getUserFile(Class someClass, String resourceFile, String user if (someClass == null || resourceFile == null || userFile == null) { return null; } - File file = new File(UserFilePath + "/" + userFile); + File file = new File(AppDataRoot + "/" + userFile); if (file.exists()) { if (deleteExisted) { file.delete(); diff --git a/MyBox/src/main/java/mara/mybox/fxml/FxmlCoverTools.java b/MyBox/src/main/java/mara/mybox/fxml/image/FxmlCoverTools.java similarity index 96% rename from MyBox/src/main/java/mara/mybox/fxml/FxmlCoverTools.java rename to MyBox/src/main/java/mara/mybox/fxml/image/FxmlCoverTools.java index 0bce42037..4b5e835c2 100644 --- a/MyBox/src/main/java/mara/mybox/fxml/FxmlCoverTools.java +++ b/MyBox/src/main/java/mara/mybox/fxml/image/FxmlCoverTools.java @@ -1,4 +1,4 @@ -package mara.mybox.fxml; +package mara.mybox.fxml.image; import java.awt.image.BufferedImage; import java.util.Random; @@ -7,7 +7,7 @@ import javafx.scene.image.PixelReader; import javafx.scene.image.PixelWriter; import javafx.scene.image.WritableImage; -import mara.mybox.image.ImageConvertTools; +import mara.mybox.image.ImageConvert; /** * @Author Mara @@ -120,7 +120,7 @@ public static Image addPicture(Image image, Image picture, int x, int y, int w, } BufferedImage source = SwingFXUtils.fromFXImage(image, null); BufferedImage pic = SwingFXUtils.fromFXImage(picture, null); - BufferedImage target = ImageConvertTools.addPicture(source, pic, x, y, w, h, keepRatio, transparent); + BufferedImage target = ImageConvert.addPicture(source, pic, x, y, w, h, keepRatio, transparent); Image newImage = SwingFXUtils.toFXImage(target, null); return newImage; } diff --git a/MyBox/src/main/java/mara/mybox/fxml/FxmlMarginsTools.java b/MyBox/src/main/java/mara/mybox/fxml/image/FxmlMarginsTools.java similarity index 93% rename from MyBox/src/main/java/mara/mybox/fxml/FxmlMarginsTools.java rename to MyBox/src/main/java/mara/mybox/fxml/image/FxmlMarginsTools.java index 4506fddac..5c619e56c 100644 --- a/MyBox/src/main/java/mara/mybox/fxml/FxmlMarginsTools.java +++ b/MyBox/src/main/java/mara/mybox/fxml/image/FxmlMarginsTools.java @@ -1,4 +1,4 @@ -package mara.mybox.fxml; +package mara.mybox.fxml.image; import javafx.scene.Group; import javafx.scene.SnapshotParameters; @@ -11,8 +11,8 @@ import javafx.scene.image.PixelWriter; import javafx.scene.image.WritableImage; import javafx.scene.paint.Color; -import static mara.mybox.fxml.FxmlImageTools.cropImage; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.fxml.image.ImageTools.cropImage; +import static mara.mybox.value.AppVaribles.logger; /** * @Author Mara @@ -60,12 +60,12 @@ public static Image cutMarginsByColor(Image image, Color mColor, int colorDistan PixelReader pixelReader = image.getPixelReader(); int top = 0, bottom = height - 1, left = 0, right = width - 1; - double d = colorDistance / 255.0; + int distance2 = colorDistance * colorDistance; if (cutTop) { for (int j = 0; j < height; j++) { boolean notMatch = false; for (int i = 0; i < width; i++) { - if (!FxmlColorTools.isColorMatch(pixelReader.getColor(i, j), mColor, d)) { + if (!ImageTools.isColorMatch2(pixelReader.getColor(i, j), mColor, distance2)) { // logger.debug("notMatch: " + i + " " + j + " " + color); notMatch = true; break; @@ -85,7 +85,7 @@ public static Image cutMarginsByColor(Image image, Color mColor, int colorDistan for (int j = height - 1; j >= 0; j--) { boolean notMatch = false; for (int i = 0; i < width; i++) { - if (!FxmlColorTools.isColorMatch(pixelReader.getColor(i, j), mColor, d)) { + if (!ImageTools.isColorMatch2(pixelReader.getColor(i, j), mColor, distance2)) { notMatch = true; break; } @@ -104,7 +104,7 @@ public static Image cutMarginsByColor(Image image, Color mColor, int colorDistan for (int i = 0; i < width; i++) { boolean notMatch = false; for (int j = 0; j < height; j++) { - if (!FxmlColorTools.isColorMatch(pixelReader.getColor(i, j), mColor, d)) { + if (!ImageTools.isColorMatch2(pixelReader.getColor(i, j), mColor, distance2)) { notMatch = true; break; } @@ -123,7 +123,7 @@ public static Image cutMarginsByColor(Image image, Color mColor, int colorDistan for (int i = width - 1; i >= 0; i--) { boolean notMatch = false; for (int j = 0; j < height; j++) { - if (!FxmlColorTools.isColorMatch(pixelReader.getColor(i, j), mColor, d)) { + if (!ImageTools.isColorMatch2(pixelReader.getColor(i, j), mColor, distance2)) { notMatch = true; break; } diff --git a/MyBox/src/main/java/mara/mybox/fxml/image/FxmlScopeTools.java b/MyBox/src/main/java/mara/mybox/fxml/image/FxmlScopeTools.java new file mode 100644 index 000000000..1f1988797 --- /dev/null +++ b/MyBox/src/main/java/mara/mybox/fxml/image/FxmlScopeTools.java @@ -0,0 +1,39 @@ +package mara.mybox.fxml.image; + +import mara.mybox.fxml.image.ImageTools; +import java.awt.image.BufferedImage; +import javafx.embed.swing.SwingFXUtils; +import javafx.scene.image.Image; +import javafx.scene.paint.Color; +import mara.mybox.image.ImageScopeTools; +import mara.mybox.data.IntCircle; +import mara.mybox.data.IntRectangle; + +/** + * @Author Mara + * @CreateDate 2018-11-10 19:44:49 + * @Version 1.0 + * @Description + * @License Apache License Version 2.0 + */ +public class FxmlScopeTools { + + public static Image indicateRectangle(Image image, + Color color, int lineWidth, IntRectangle rect) { + BufferedImage source = SwingFXUtils.fromFXImage(image, null); + BufferedImage target = ImageScopeTools.indicateRectangle(source, + ImageTools.colorConvert(color), lineWidth, rect); + Image newImage = SwingFXUtils.toFXImage(target, null); + return newImage; + } + + public static Image indicateCircle(Image image, + Color color, int lineWidth, IntCircle circle) { + BufferedImage source = SwingFXUtils.fromFXImage(image, null); + BufferedImage target = ImageScopeTools.indicateCircle(source, + ImageTools.colorConvert(color), lineWidth, circle); + Image newImage = SwingFXUtils.toFXImage(target, null); + return newImage; + } + +} diff --git a/MyBox/src/main/java/mara/mybox/fxml/FxmlTransformTools.java b/MyBox/src/main/java/mara/mybox/fxml/image/FxmlTransformTools.java similarity index 91% rename from MyBox/src/main/java/mara/mybox/fxml/FxmlTransformTools.java rename to MyBox/src/main/java/mara/mybox/fxml/image/FxmlTransformTools.java index b6e0393a3..194a7e596 100644 --- a/MyBox/src/main/java/mara/mybox/fxml/FxmlTransformTools.java +++ b/MyBox/src/main/java/mara/mybox/fxml/image/FxmlTransformTools.java @@ -1,4 +1,4 @@ -package mara.mybox.fxml; +package mara.mybox.fxml.image; import java.awt.image.BufferedImage; import javafx.embed.swing.SwingFXUtils; @@ -7,7 +7,7 @@ import javafx.scene.image.PixelWriter; import javafx.scene.image.WritableImage; import javafx.scene.paint.Color; -import mara.mybox.image.ImageTransformTools; +import mara.mybox.image.ImageTransform; /** * @Author Mara @@ -20,7 +20,7 @@ public class FxmlTransformTools { public static Image rotateImage(Image image, int angle) { BufferedImage source = SwingFXUtils.fromFXImage(image, null); - BufferedImage target = ImageTransformTools.rotateImage(source, angle); + BufferedImage target = ImageTransform.rotateImage(source, angle); Image newImage = SwingFXUtils.toFXImage(target, null); return newImage; } @@ -68,7 +68,7 @@ public static Image verticalImage(Image image) { public static Image shearImage(Image image, float shearX, float shearY) { BufferedImage source = SwingFXUtils.fromFXImage(image, null); - BufferedImage target = ImageTransformTools.shearImage(source, shearX, shearY); + BufferedImage target = ImageTransform.shearImage(source, shearX, shearY); Image newImage = SwingFXUtils.toFXImage(target, null); return newImage; } diff --git a/MyBox/src/main/java/mara/mybox/fxml/image/ImageBinary.java b/MyBox/src/main/java/mara/mybox/fxml/image/ImageBinary.java new file mode 100644 index 000000000..c8f01f88b --- /dev/null +++ b/MyBox/src/main/java/mara/mybox/fxml/image/ImageBinary.java @@ -0,0 +1,62 @@ +package mara.mybox.fxml.image; + +import java.awt.image.BufferedImage; +import javafx.embed.swing.SwingFXUtils; +import javafx.scene.image.Image; +import mara.mybox.image.ImageScope; + +/** + * @Author Mara + * @CreateDate 2019-2-15 16:54:15 + * @Version 1.0 + * @Description + * @License Apache License Version 2.0 + */ +public class ImageBinary extends mara.mybox.image.ImageBinary { + + public ImageBinary() { + intPara1 = -1; + grayed = false; + this.operationType = OperationType.BlackOrWhite; + } + + public ImageBinary(Image image) { + this.image = SwingFXUtils.fromFXImage(image, null); + this.operationType = OperationType.BlackOrWhite; + intPara1 = -1; + grayed = false; + } + + public ImageBinary(Image image, ImageScope scope) { + this.image = SwingFXUtils.fromFXImage(image, null); + this.scope = scope; + this.operationType = OperationType.BlackOrWhite; + intPara1 = -1; + grayed = false; + } + + public ImageBinary(Image image, int threshold) { + this.image = SwingFXUtils.fromFXImage(image, null); + this.scope = null; + this.operationType = OperationType.BlackOrWhite; + intPara1 = threshold; + grayed = false; + } + + public ImageBinary(Image image, ImageScope scope, int threshold) { + this.image = SwingFXUtils.fromFXImage(image, null); + this.operationType = OperationType.BlackOrWhite; + this.scope = scope; + intPara1 = threshold; + grayed = false; + } + + public Image operateFxImage() { + BufferedImage target = operate(); + if (target == null) { + return null; + } + return SwingFXUtils.toFXImage(target, null); + } + +} diff --git a/MyBox/src/main/java/mara/mybox/fxml/image/ImageContrast.java b/MyBox/src/main/java/mara/mybox/fxml/image/ImageContrast.java new file mode 100644 index 000000000..680a5ff4a --- /dev/null +++ b/MyBox/src/main/java/mara/mybox/fxml/image/ImageContrast.java @@ -0,0 +1,51 @@ +package mara.mybox.fxml.image; + +import java.awt.image.BufferedImage; +import javafx.embed.swing.SwingFXUtils; +import javafx.scene.image.Image; + +/** + * @Author Mara + * @CreateDate 2019-2-15 16:54:15 + * @Version 1.0 + * @Description + * @License Apache License Version 2.0 + */ +public class ImageContrast extends mara.mybox.image.ImageContrast { + + public ImageContrast() { + this.operationType = OperationType.Contrast; + } + + public ImageContrast(Image image) { + this.image = SwingFXUtils.fromFXImage(image, null); + this.operationType = OperationType.Contrast; + } + + public ImageContrast(Image image, ContrastAlgorithm algorithm) { + this.image = SwingFXUtils.fromFXImage(image, null); + this.operationType = OperationType.Contrast; + this.algorithm = algorithm; + } + + public Image operateFxImage() { + BufferedImage target = super.operate(); + if (target == null) { + return null; + } + return SwingFXUtils.toFXImage(target, null); + } + + public static Image grayHistogramEqualization(Image grayImage) { + BufferedImage image = SwingFXUtils.fromFXImage(grayImage, null); + image = mara.mybox.image.ImageContrast.grayHistogramEqualization(image); + return SwingFXUtils.toFXImage(image, null); + } + + public static Image brightnessHistogramEqualization(Image colorImage) { + BufferedImage image = SwingFXUtils.fromFXImage(colorImage, null); + image = mara.mybox.image.ImageContrast.brightnessHistogramEqualization(image); + return SwingFXUtils.toFXImage(image, null); + } + +} diff --git a/MyBox/src/main/java/mara/mybox/fxml/image/ImageConvolution.java b/MyBox/src/main/java/mara/mybox/fxml/image/ImageConvolution.java new file mode 100644 index 000000000..7244cb790 --- /dev/null +++ b/MyBox/src/main/java/mara/mybox/fxml/image/ImageConvolution.java @@ -0,0 +1,59 @@ +package mara.mybox.fxml.image; + +import java.awt.image.BufferedImage; +import javafx.embed.swing.SwingFXUtils; +import javafx.scene.image.Image; +import mara.mybox.image.ImageScope; +import mara.mybox.data.ConvolutionKernel; + +/** + * @Author Mara + * @CreateDate 2019-2-15 16:54:15 + * @Version 1.0 + * @Description + * @License Apache License Version 2.0 + */ +public class ImageConvolution extends mara.mybox.image.ImageConvolution { + + public ImageConvolution() { + this.operationType = OperationType.Convolution; + } + + public ImageConvolution(Image image) { + this.image = SwingFXUtils.fromFXImage(image, null); + this.operationType = OperationType.Convolution; + } + + public ImageConvolution(Image image, ImageScope scope) { + this.image = SwingFXUtils.fromFXImage(image, null); + this.operationType = OperationType.Convolution; + this.scope = scope; + } + + public ImageConvolution(Image image, ConvolutionKernel kernel) { + this.image = SwingFXUtils.fromFXImage(image, null); + this.operationType = OperationType.Convolution; + this.scope = null; + init(kernel); + } + + public ImageConvolution(Image image, ImageScope scope, ConvolutionKernel kernel) { + this.image = SwingFXUtils.fromFXImage(image, null); + this.operationType = OperationType.Convolution; + this.scope = scope; + init(kernel); + } + + private void init(ConvolutionKernel kernel) { + setKernel(kernel); + } + + public Image operateFxImage() { + BufferedImage target = operate(); + if (target == null) { + return null; + } + return SwingFXUtils.toFXImage(target, null); + } + +} diff --git a/MyBox/src/main/java/mara/mybox/fxml/image/ImageGray.java b/MyBox/src/main/java/mara/mybox/fxml/image/ImageGray.java new file mode 100644 index 000000000..3321049f4 --- /dev/null +++ b/MyBox/src/main/java/mara/mybox/fxml/image/ImageGray.java @@ -0,0 +1,40 @@ +package mara.mybox.fxml.image; + +import java.awt.image.BufferedImage; +import javafx.embed.swing.SwingFXUtils; +import javafx.scene.image.Image; +import mara.mybox.image.ImageScope; + +/** + * @Author Mara + * @CreateDate 2019-2-15 16:54:15 + * @Version 1.0 + * @Description + * @License Apache License Version 2.0 + */ +public class ImageGray extends mara.mybox.image.ImageGray { + + public ImageGray() { + this.operationType = OperationType.Gray; + } + + public ImageGray(Image image) { + this.image = SwingFXUtils.fromFXImage(image, null); + this.operationType = OperationType.Gray; + } + + public ImageGray(Image image, ImageScope scope) { + this.image = SwingFXUtils.fromFXImage(image, null); + this.operationType = OperationType.Gray; + this.scope = scope; + } + + public Image operateFxImage() { + BufferedImage target = operate(); + if (target == null) { + return null; + } + return SwingFXUtils.toFXImage(target, null); + } + +} diff --git a/MyBox/src/main/java/mara/mybox/fxml/image/ImageQuantization.java b/MyBox/src/main/java/mara/mybox/fxml/image/ImageQuantization.java new file mode 100644 index 000000000..66fd56c8f --- /dev/null +++ b/MyBox/src/main/java/mara/mybox/fxml/image/ImageQuantization.java @@ -0,0 +1,33 @@ +package mara.mybox.fxml.image; + +import java.awt.image.BufferedImage; +import javafx.embed.swing.SwingFXUtils; +import javafx.scene.image.Image; + +/** + * @Author Mara + * @CreateDate 2019-2-15 16:54:15 + * @Version 1.0 + * @Description + * @License Apache License Version 2.0 + */ +public class ImageQuantization extends mara.mybox.image.ImageQuantization { + + public ImageQuantization() { + this.operationType = OperationType.Quantization; + } + + public ImageQuantization(Image image) { + this.image = SwingFXUtils.fromFXImage(image, null); + this.operationType = OperationType.Quantization; + } + + public Image operateFxImage() { + BufferedImage target = operate(); + if (target == null) { + return null; + } + return SwingFXUtils.toFXImage(target, null); + } + +} diff --git a/MyBox/src/main/java/mara/mybox/fxml/FxmlImageTools.java b/MyBox/src/main/java/mara/mybox/fxml/image/ImageTools.java similarity index 91% rename from MyBox/src/main/java/mara/mybox/fxml/FxmlImageTools.java rename to MyBox/src/main/java/mara/mybox/fxml/image/ImageTools.java index baf176b83..c6ff4187d 100644 --- a/MyBox/src/main/java/mara/mybox/fxml/FxmlImageTools.java +++ b/MyBox/src/main/java/mara/mybox/fxml/image/ImageTools.java @@ -1,4 +1,4 @@ -package mara.mybox.fxml; +package mara.mybox.fxml.image; import java.awt.image.BufferedImage; import java.util.List; @@ -23,14 +23,14 @@ import javafx.scene.shape.Rectangle; import javafx.scene.text.Font; import javafx.scene.text.Text; -import mara.mybox.image.ImageBlendTools; -import mara.mybox.image.ImageBlendTools.ImagesBlendMode; -import mara.mybox.image.ImageBlendTools.ImagesRelativeLocation; -import mara.mybox.image.ImageConvertTools; +import mara.mybox.image.ImageBlend; +import mara.mybox.image.ImageBlend.ImagesBlendMode; +import mara.mybox.image.ImageBlend.ImagesRelativeLocation; +import mara.mybox.image.ImageConvert; import mara.mybox.image.ImageScopeTools; -import mara.mybox.objects.ImageCombine; -import mara.mybox.objects.ImageInformation; -import static mara.mybox.objects.AppVaribles.logger; +import mara.mybox.data.ImageCombine; +import mara.mybox.data.ImageInformation; +import static mara.mybox.value.AppVaribles.logger; /** * @Author Mara @@ -38,7 +38,7 @@ * @Description * @License Apache License Version 2.0 */ -public class FxmlImageTools { +public class ImageTools { public class ImageManufactureType { @@ -102,25 +102,25 @@ public static BufferedImage getBufferedImage(Image image) { public static BufferedImage checkAlpha(Image image, String format) { BufferedImage source = SwingFXUtils.fromFXImage(image, null); - BufferedImage target = ImageConvertTools.checkAlpha(source, format); + BufferedImage target = ImageConvert.checkAlpha(source, format); return target; } public static BufferedImage clearAlpha(Image image) { BufferedImage source = SwingFXUtils.fromFXImage(image, null); - BufferedImage target = ImageConvertTools.clearAlpha(source); + BufferedImage target = ImageConvert.clearAlpha(source); return target; } - public static Image scaleImage(Image image, String format, float scale) { + public static Image scaleImage(Image image, float scale) { int targetW = (int) Math.round(image.getWidth() * scale); int targetH = (int) Math.round(image.getHeight() * scale); - return scaleImage(image, format, targetW, targetH); + return scaleImage(image, targetW, targetH); } - public static Image scaleImage(Image image, String format, int width, int height) { + public static Image scaleImage(Image image, int width, int height) { BufferedImage source = SwingFXUtils.fromFXImage(image, null); - BufferedImage target = ImageConvertTools.scaleImage(source, width, height); + BufferedImage target = ImageConvert.scaleImage(source, width, height); Image newImage = SwingFXUtils.toFXImage(target, null); return newImage; } @@ -129,8 +129,8 @@ public static Image addText(Image image, String textString, java.awt.Font font, Color color, int x, int y, float transparent, int shadow, int angle, boolean isOutline) { BufferedImage source = SwingFXUtils.fromFXImage(image, null); - BufferedImage target = ImageConvertTools.addText(source, textString, - font, FxmlImageTools.colorConvert(color), x, y, transparent, shadow, angle, isOutline); + BufferedImage target = ImageConvert.addText(source, textString, + font, ImageTools.colorConvert(color), x, y, transparent, shadow, angle, isOutline); Image newImage = SwingFXUtils.toFXImage(target, null); return newImage; } @@ -176,7 +176,7 @@ public static Image addArc(Image image, int arc, Color bgColor) { return image; } BufferedImage source = SwingFXUtils.fromFXImage(image, null); - BufferedImage target = ImageConvertTools.addArc(source, arc, FxmlImageTools.colorConvert(bgColor)); + BufferedImage target = ImageConvert.addArc(source, arc, ImageTools.colorConvert(bgColor)); Image newImage = SwingFXUtils.toFXImage(target, null); return newImage; } @@ -259,7 +259,7 @@ public static Image addShadow(Image image, int shadow, Color color) { return image; } BufferedImage source = SwingFXUtils.fromFXImage(image, null); - BufferedImage target = ImageConvertTools.addShadow(source, shadow, FxmlImageTools.colorConvert(color)); + BufferedImage target = ImageConvert.addShadow(source, shadow, ImageTools.colorConvert(color)); Image newImage = SwingFXUtils.toFXImage(target, null); return newImage; } @@ -401,7 +401,7 @@ public static Image cropImage(Image image, int x1, int y1, int x2, int y2) { int height = (int) image.getHeight(); if (x1 >= x2 || y1 >= y2 || x1 < 0 || x2 < 0 || y1 < 0 || y2 < 0 - || x2 > width || y2 > height) { + || x2 >= width || y2 >= height) { return image; } int w = x2 - x1 + 1; @@ -426,7 +426,7 @@ public static Image indicateSplit(Image image, } BufferedImage source = SwingFXUtils.fromFXImage(image, null); BufferedImage target = ImageScopeTools.indicateSplit(source, rows, cols, - FxmlImageTools.colorConvert(lineColor), lineWidth, showSize, scale); + ImageTools.colorConvert(lineColor), lineWidth, showSize, scale); Image newImage = SwingFXUtils.toFXImage(target, null); return newImage; } @@ -545,7 +545,7 @@ public static Image combineSingleColumn(List images) { if (images == null || images.isEmpty()) { return null; } - BufferedImage target = ImageConvertTools.combineSingleColumn(images); + BufferedImage target = ImageConvert.combineSingleColumn(images); Image newImage = SwingFXUtils.toFXImage(target, null); return newImage; } @@ -763,7 +763,7 @@ public static Image blurBottomMargin(Image image, int size) { for (int x = 0; x < image.getWidth(); x++) { for (int y = 0; y < height; y++) { Color color = pixelReader.getColor(x, y); - if (color == Color.TRANSPARENT || y <= height - size) { + if (color.equals(Color.TRANSPARENT) || y <= height - size) { pixelWriter.setColor(x, y, color); continue; } @@ -799,7 +799,7 @@ public static Image blurLeftMargin(Image image, int size) { for (int y = 0; y < image.getHeight(); y++) { for (int x = 0; x < width; x++) { Color color = pixelReader.getColor(x, y); - if (color == Color.TRANSPARENT || x <= width - size) { + if (color.equals(Color.TRANSPARENT) || x <= width - size) { pixelWriter.setColor(x, y, color); continue; } @@ -836,7 +836,7 @@ public static Image blurMarginsFx(Image image, int size) { for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { Color color = pixelReader.getColor(x, y); - if (color == Color.TRANSPARENT + if (color.equals(Color.TRANSPARENT) || (x <= width - size && y <= height - size)) { pixelWriter.setColor(x, y, color); continue; @@ -874,7 +874,7 @@ public static Image blendImages(Image foreImage, Image backImage, } BufferedImage source1 = SwingFXUtils.fromFXImage(foreImage, null); BufferedImage source2 = SwingFXUtils.fromFXImage(backImage, null); - BufferedImage target = ImageBlendTools.blendImages(source1, source2, + BufferedImage target = ImageBlend.blendImages(source1, source2, location, x, y, intersectOnly, blendMode, opacity); if (target == null) { target = source1; @@ -883,4 +883,43 @@ public static Image blendImages(Image foreImage, Image backImage, return newImage; } + public static boolean isImageSame(Image imageA, Image imageB) { + if (imageA == null || imageB == null + || imageA.getWidth() != imageB.getWidth() + || imageA.getHeight() != imageB.getHeight()) { + return false; + } + PixelReader readA = imageA.getPixelReader(); + PixelReader readB = imageB.getPixelReader(); + for (int y = 0; y < imageA.getHeight(); y++) { + for (int x = 0; x < imageA.getWidth(); x++) { + if (!readA.getColor(x, y).equals(readB.getColor(x, y))) { + return false; + } + } + } + return true; + } + + public static int calculateColorDistance2(Color color1, Color color2) { + int redDiff = (int) (color1.getRed() - color2.getRed()) * 255; + int greenDiff = (int) (color1.getGreen() - color2.getGreen()) * 255; + int blueDiff = (int) (color1.getBlue() - color2.getBlue()) * 255; + int v = (int) Math.round(2 * redDiff * redDiff + + 4 * greenDiff * greenDiff + + 3 * blueDiff * blueDiff); + return v; + } + + // distance2 = Math.pow(distance, 2) + // distance: 0-255 + public static boolean isColorMatch2(Color color1, Color color2, int distance2) { + if (color1.equals(color2)) { + return true; + } else if (distance2 == 0) { + return false; + } + return calculateColorDistance2(color1, color2) <= distance2; + } + } diff --git a/MyBox/src/main/java/mara/mybox/fxml/image/PixelsOperation.java b/MyBox/src/main/java/mara/mybox/fxml/image/PixelsOperation.java new file mode 100644 index 000000000..ccb790457 --- /dev/null +++ b/MyBox/src/main/java/mara/mybox/fxml/image/PixelsOperation.java @@ -0,0 +1,46 @@ +package mara.mybox.fxml.image; + +import java.awt.image.BufferedImage; +import javafx.embed.swing.SwingFXUtils; +import javafx.scene.image.Image; +import mara.mybox.image.ImageScope; + +/** + * @Author Mara + * @CreateDate 2019-2-15 16:54:15 + * @Version 1.0 + * @Description + * @License Apache License Version 2.0 + */ +public class PixelsOperation extends mara.mybox.image.PixelsOperation { + + public PixelsOperation() { + } + + public PixelsOperation(Image image) { + this.image = SwingFXUtils.fromFXImage(image, null); + } + + public PixelsOperation(Image image, ImageScope scope, OperationType operationType) { + this.image = SwingFXUtils.fromFXImage(image, null); + this.operationType = operationType; + this.scope = scope; + } + + public PixelsOperation(Image image, ImageScope scope, + OperationType operationType, ColorActionType colorActionType) { + this.image = SwingFXUtils.fromFXImage(image, null); + this.operationType = operationType; + this.scope = scope; + this.colorActionType = colorActionType; + } + + public Image operateFxImage() { + BufferedImage target = operate(); + if (target == null) { + return null; + } + return SwingFXUtils.toFXImage(target, null); + } + +} diff --git a/MyBox/src/main/java/mara/mybox/image/ImageAdjustColorTools.java b/MyBox/src/main/java/mara/mybox/image/ImageAdjustColorTools.java deleted file mode 100644 index 0af3852fa..000000000 --- a/MyBox/src/main/java/mara/mybox/image/ImageAdjustColorTools.java +++ /dev/null @@ -1,541 +0,0 @@ -package mara.mybox.image; - -import java.awt.Color; -import java.awt.image.BufferedImage; -import mara.mybox.fxml.FxmlAdjustColorTools; -import mara.mybox.fxml.FxmlAdjustColorTools.ColorActionType; -import mara.mybox.fxml.FxmlAdjustColorTools.ColorObjectType; -import static mara.mybox.objects.AppVaribles.logger; - - -/** - * @Author Mara - * @CreateDate 2018-11-10 20:00:06 - * @Version 1.0 - * @Description - * @License Apache License Version 2.0 - */ -public class ImageAdjustColorTools { - - - - public static BufferedImage changeSaturate(BufferedImage source, float change) { - try { - int width = source.getWidth(); - int height = source.getHeight(); - int imageType = source.getType(); - if (imageType == BufferedImage.TYPE_CUSTOM) { - imageType = BufferedImage.TYPE_INT_ARGB; - } - BufferedImage target = new BufferedImage(width, height, imageType); - for (int j = 0; j < height; j++) { - for (int i = 0; i < width; i++) { - float[] hsb = ImageColorTools.pixel2HSB(source.getRGB(i, j)); - float v = Math.min(Math.max(hsb[1] * (1.0f + change), 0.0f), 1.0f); - Color newColor = Color.getHSBColor(hsb[0], v, hsb[2]); - target.setRGB(i, j, newColor.getRGB()); - } - } - return target; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - } - - public static BufferedImage changeBrightness(BufferedImage source, float change) { - try { - int width = source.getWidth(); - int height = source.getHeight(); - int imageType = source.getType(); - if (imageType == BufferedImage.TYPE_CUSTOM) { - imageType = BufferedImage.TYPE_INT_ARGB; - } - BufferedImage target = new BufferedImage(width, height, imageType); - for (int j = 0; j < height; j++) { - for (int i = 0; i < width; i++) { - float[] hsb = ImageColorTools.pixel2HSB(source.getRGB(i, j)); - float v = Math.min(Math.max(hsb[2] * (1.0f + change), 0.0f), 1.0f); - Color newColor = Color.getHSBColor(hsb[0], hsb[1], v); - target.setRGB(i, j, newColor.getRGB()); - } - } - return target; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - } - - public static BufferedImage changeHue(BufferedImage source, float change) { - try { - int width = source.getWidth(); - int height = source.getHeight(); - int imageType = source.getType(); - if (imageType == BufferedImage.TYPE_CUSTOM) { - imageType = BufferedImage.TYPE_INT_ARGB; - } - BufferedImage target = new BufferedImage(width, height, imageType); - for (int j = 0; j < height; j++) { - for (int i = 0; i < width; i++) { - float[] hsb = ImageColorTools.pixel2HSB(source.getRGB(i, j)); - float v = hsb[0] + change; - if (v > 1.0f) { - v = v - 1.0f; - } - if (v < 0.0f) { - v = v + 1.0f; - } - Color newColor = Color.getHSBColor(v, hsb[1], hsb[2]); - target.setRGB(i, j, newColor.getRGB()); - } - } - return target; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - } - - public static BufferedImage changeRed(BufferedImage source, int change) { - try { - int width = source.getWidth(); - int height = source.getHeight(); - int imageType = source.getType(); - if (imageType == BufferedImage.TYPE_CUSTOM) { - imageType = BufferedImage.TYPE_INT_ARGB; - } - BufferedImage target = new BufferedImage(width, height, imageType); - Color newColor; - for (int j = 0; j < height; j++) { - for (int i = 0; i < width; i++) { - Color color = new Color(source.getRGB(i, j), true); - int red = Math.min(Math.max(color.getRed() + change, 0), 255); - newColor = new Color(red, color.getGreen(), color.getBlue(), color.getAlpha()); - target.setRGB(i, j, newColor.getRGB()); - } - } - return target; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - } - - public static BufferedImage changeGreen(BufferedImage source, int change) { - try { - int width = source.getWidth(); - int height = source.getHeight(); - int imageType = source.getType(); - if (imageType == BufferedImage.TYPE_CUSTOM) { - imageType = BufferedImage.TYPE_INT_ARGB; - } - BufferedImage target = new BufferedImage(width, height, imageType); - Color newColor; - for (int j = 0; j < height; j++) { - for (int i = 0; i < width; i++) { - Color color = new Color(source.getRGB(i, j), true); - int green = Math.min(Math.max(color.getGreen() + change, 0), 255); - newColor = new Color(color.getRed(), green, color.getBlue(), color.getAlpha()); - target.setRGB(i, j, newColor.getRGB()); - } - } - return target; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - } - - public static BufferedImage changeBlue(BufferedImage source, int change) { - try { - int width = source.getWidth(); - int height = source.getHeight(); - int imageType = source.getType(); - if (imageType == BufferedImage.TYPE_CUSTOM) { - imageType = BufferedImage.TYPE_INT_ARGB; - } - BufferedImage target = new BufferedImage(width, height, imageType); - Color newColor; - for (int j = 0; j < height; j++) { - for (int i = 0; i < width; i++) { - Color color = new Color(source.getRGB(i, j), true); - int blue = Math.min(Math.max(color.getBlue() + change, 0), 255); - newColor = new Color(color.getRed(), color.getGreen(), blue, color.getAlpha()); - target.setRGB(i, j, newColor.getRGB()); - } - } - return target; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - } - - public static BufferedImage changeYellow(BufferedImage source, int change) { - try { - int width = source.getWidth(); - int height = source.getHeight(); - int imageType = source.getType(); - if (imageType == BufferedImage.TYPE_CUSTOM) { - imageType = BufferedImage.TYPE_INT_ARGB; - } - BufferedImage target = new BufferedImage(width, height, imageType); - Color newColor; - for (int j = 0; j < height; j++) { - for (int i = 0; i < width; i++) { - Color color = new Color(source.getRGB(i, j), true); - int red = Math.min(Math.max(color.getRed() + change, 0), 255); - int green = Math.min(Math.max(color.getGreen() + change, 0), 255); - newColor = new Color(red, green, color.getBlue(), color.getAlpha()); - target.setRGB(i, j, newColor.getRGB()); - } - } - return target; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - } - - public static BufferedImage changeCyan(BufferedImage source, int change) { - try { - int width = source.getWidth(); - int height = source.getHeight(); - int imageType = source.getType(); - if (imageType == BufferedImage.TYPE_CUSTOM) { - imageType = BufferedImage.TYPE_INT_ARGB; - } - BufferedImage target = new BufferedImage(width, height, imageType); - Color newColor; - for (int j = 0; j < height; j++) { - for (int i = 0; i < width; i++) { - Color color = new Color(source.getRGB(i, j), true); - int green = Math.min(Math.max(color.getGreen() + change, 0), 255); - int blue = Math.min(Math.max(color.getBlue() + change, 0), 255); - newColor = new Color(color.getRed(), green, blue, color.getAlpha()); - target.setRGB(i, j, newColor.getRGB()); - } - } - return target; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - } - - public static BufferedImage changeMagenta(BufferedImage source, int change) { - try { - int width = source.getWidth(); - int height = source.getHeight(); - int imageType = source.getType(); - if (imageType == BufferedImage.TYPE_CUSTOM) { - imageType = BufferedImage.TYPE_INT_ARGB; - } - BufferedImage target = new BufferedImage(width, height, imageType); - Color newColor; - for (int j = 0; j < height; j++) { - for (int i = 0; i < width; i++) { - Color color = new Color(source.getRGB(i, j), true); - int red = Math.min(Math.max(color.getRed() + change, 0), 255); - int blue = Math.min(Math.max(color.getBlue() + change, 0), 255); - newColor = new Color(red, color.getGreen(), blue, color.getAlpha()); - target.setRGB(i, j, newColor.getRGB()); - } - } - return target; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - } - - public static BufferedImage changeRGB(BufferedImage source, int change) { - try { - int width = source.getWidth(); - int height = source.getHeight(); - int imageType = source.getType(); - if (imageType == BufferedImage.TYPE_CUSTOM) { - imageType = BufferedImage.TYPE_INT_ARGB; - } - BufferedImage target = new BufferedImage(width, height, imageType); - Color newColor; - for (int j = 0; j < height; j++) { - for (int i = 0; i < width; i++) { - Color color = new Color(source.getRGB(i, j), true); - int red = Math.min(Math.max(color.getRed() + change, 0), 255); - int green = Math.min(Math.max(color.getGreen() + change, 0), 255); - int blue = Math.min(Math.max(color.getBlue() + change, 0), 255); - newColor = new Color(red, green, blue, color.getAlpha()); - target.setRGB(i, j, newColor.getRGB()); - } - } - return target; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - } - - public static BufferedImage addAlpha(BufferedImage src, int alpha) { - try { - int width = src.getWidth(); - int height = src.getHeight(); - BufferedImage target = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); - for (int j = 0; j < height; j++) { - for (int i = 0; i < width; i++) { - int rgb = src.getRGB(i, j); - Color color = new Color(rgb, true); - Color newcolor = new Color(color.getRed(), color.getGreen(), color.getBlue(), alpha); - target.setRGB(i, j, newcolor.getRGB()); - } - } - return target; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - } - - public static BufferedImage changeColor(BufferedImage source, - ColorObjectType objectType, ColorActionType actionType, float change) { - try { - int width = source.getWidth(); - int height = source.getHeight(); - BufferedImage target = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); - for (int j = 0; j < height; j++) { - for (int i = 0; i < width; i++) { - int pixel = source.getRGB(i, j); - Color newColor = changeColor(pixel, objectType, actionType, change); - target.setRGB(i, j, newColor.getRGB()); - } - } - return target; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - } - - public static Color changeColor(int pixel, - ColorObjectType type, ColorActionType actionType, float change) { - Color newColor = new Color(pixel, true); - try { - int red, blue, green, intChange = (int) change; - float v; - float[] hsb; - switch (type) { - case Brightness: - hsb = ImageColorTools.pixel2HSB(pixel); - if (actionType == FxmlAdjustColorTools.ColorActionType.Set) { - v = change; - } else { - v = hsb[2] * (1.0f + change); - } - v = Math.min(Math.max(v, 0.0f), 1.0f); - newColor = Color.getHSBColor(hsb[0], hsb[1], v); - break; - case Sauration: - hsb = ImageColorTools.pixel2HSB(pixel); - if (actionType == FxmlAdjustColorTools.ColorActionType.Set) { - v = change; - } else { - v = hsb[1] * (1.0f + change); - } - v = Math.min(Math.max(v, 0.0f), 1.0f); - newColor = Color.getHSBColor(hsb[0], v, hsb[2]); - break; - case Hue: - hsb = ImageColorTools.pixel2HSB(pixel); - if (actionType == FxmlAdjustColorTools.ColorActionType.Set) { - v = change; - } else { - v = hsb[0] + change; - } - if (v > 1.0f) { - v = v - 1.0f; - } - if (v < 0.0f) { - v = v + 1.0f; - } - v = Math.min(Math.max(v, 0.0f), 1.0f); - newColor = Color.getHSBColor(v, hsb[1], hsb[2]); - break; - case Opacity: - intChange = Math.min(Math.max(intChange, 0), 255); - newColor = new Color(newColor.getRed(), newColor.getGreen(), newColor.getBlue(), intChange); - break; - case Red: - switch (actionType) { - case Set: - red = intChange; - red = Math.min(Math.max(red, 0), 255); - newColor = new Color(red, newColor.getGreen(), newColor.getBlue(), newColor.getAlpha()); - break; - case Increase: - case Decrease: - red = newColor.getRed() + intChange; - red = Math.min(Math.max(red, 0), 255); - newColor = new Color(red, newColor.getGreen(), newColor.getBlue(), newColor.getAlpha()); - break; - case Filter: - newColor = new Color(newColor.getRed(), 0, 0, newColor.getAlpha()); - break; - case Invert: - newColor = new Color(255 - newColor.getRed(), newColor.getGreen(), newColor.getBlue(), newColor.getAlpha()); - break; - } - break; - case Green: - switch (actionType) { - case Set: - green = intChange; - green = Math.min(Math.max(green, 0), 255); - newColor = new Color(newColor.getRed(), green, newColor.getBlue(), newColor.getAlpha()); - break; - case Increase: - case Decrease: - green = newColor.getGreen() + intChange; - green = Math.min(Math.max(green, 0), 255); - newColor = new Color(newColor.getRed(), green, newColor.getBlue(), newColor.getAlpha()); - break; - case Filter: - newColor = new Color(0, newColor.getGreen(), 0, newColor.getAlpha()); - break; - case Invert: - newColor = new Color(newColor.getRed(), 255 - newColor.getGreen(), newColor.getBlue(), newColor.getAlpha()); - break; - } - break; - case Blue: - switch (actionType) { - case Set: - blue = intChange; - blue = Math.min(Math.max(blue, 0), 255); - newColor = new Color(newColor.getRed(), newColor.getGreen(), blue, newColor.getAlpha()); - break; - case Increase: - case Decrease: - blue = newColor.getBlue() + intChange; - blue = Math.min(Math.max(blue, 0), 255); - newColor = new Color(newColor.getRed(), newColor.getGreen(), blue, newColor.getAlpha()); - break; - case Filter: - newColor = new Color(0, 0, newColor.getBlue(), newColor.getAlpha()); - break; - case Invert: - newColor = new Color(newColor.getRed(), newColor.getGreen(), 255 - newColor.getBlue(), newColor.getAlpha()); - break; - } - break; - case Yellow: - switch (actionType) { - case Set: - red = intChange; - green = intChange; - red = Math.min(Math.max(red, 0), 255); - green = Math.min(Math.max(green, 0), 255); - newColor = new Color(red, green, newColor.getBlue(), newColor.getAlpha()); - break; - case Increase: - case Decrease: - red = newColor.getRed() + intChange; - green = newColor.getGreen() + intChange; - red = Math.min(Math.max(red, 0), 255); - green = Math.min(Math.max(green, 0), 255); - newColor = new Color(red, green, newColor.getBlue(), newColor.getAlpha()); - break; - case Filter: - newColor = new Color(newColor.getRed(), newColor.getGreen(), 0, newColor.getAlpha()); - break; - case Invert: - newColor = new Color(255 - newColor.getRed(), 255 - newColor.getGreen(), newColor.getBlue(), newColor.getAlpha()); - break; - } - break; - case Cyan: - switch (actionType) { - case Set: - blue = intChange; - green = intChange; - blue = Math.min(Math.max(blue, 0), 255); - green = Math.min(Math.max(green, 0), 255); - newColor = new Color(newColor.getRed(), green, blue, newColor.getAlpha()); - break; - case Increase: - case Decrease: - blue = newColor.getBlue() + intChange; - green = newColor.getGreen() + intChange; - blue = Math.min(Math.max(blue, 0), 255); - green = Math.min(Math.max(green, 0), 255); - newColor = new Color(newColor.getRed(), green, blue, newColor.getAlpha()); - break; - case Filter: - newColor = new Color(0, newColor.getGreen(), newColor.getBlue(), newColor.getAlpha()); - break; - case Invert: - newColor = new Color(newColor.getRed(), 255 - newColor.getGreen(), 255 - newColor.getBlue(), newColor.getAlpha()); - break; - } - break; - case Magenta: - switch (actionType) { - case Set: - red = intChange; - blue = intChange; - red = Math.min(Math.max(red, 0), 255); - blue = Math.min(Math.max(blue, 0), 255); - newColor = new Color(red, newColor.getGreen(), blue, newColor.getAlpha()); - break; - case Increase: - case Decrease: - red = newColor.getRed() + intChange; - blue = newColor.getBlue() + intChange; - red = Math.min(Math.max(red, 0), 255); - blue = Math.min(Math.max(blue, 0), 255); - newColor = new Color(red, newColor.getGreen(), blue, newColor.getAlpha()); - break; - case Filter: - newColor = new Color(newColor.getRed(), 0, newColor.getBlue(), newColor.getAlpha()); - break; - case Invert: - newColor = new Color(255 - newColor.getRed(), newColor.getGreen(), 255 - newColor.getBlue(), newColor.getAlpha()); - break; - } - break; - case RGB: - switch (actionType) { - case Set: - blue = intChange; - green = intChange; - red = intChange; - red = Math.min(Math.max(red, 0), 255); - green = Math.min(Math.max(green, 0), 255); - blue = Math.min(Math.max(blue, 0), 255); - newColor = new Color(red, green, blue, newColor.getAlpha()); - break; - case Increase: - case Decrease: - blue = newColor.getBlue() + intChange; - green = newColor.getGreen() + intChange; - red = newColor.getRed() + intChange; - red = Math.min(Math.max(red, 0), 255); - green = Math.min(Math.max(green, 0), 255); - blue = Math.min(Math.max(blue, 0), 255); - newColor = new Color(red, green, blue, newColor.getAlpha()); - break; - case Invert: - newColor = new Color(255 - newColor.getRed(), 255 - newColor.getGreen(), 255 - newColor.getBlue(), newColor.getAlpha()); - break; - } - break; - default: - break; - } - } catch (Exception e) { - logger.error(e.toString()); - } - return newColor; - } - -} diff --git a/MyBox/src/main/java/mara/mybox/image/ImageAnalyzeTools.java b/MyBox/src/main/java/mara/mybox/image/ImageAnalyzeTools.java index ccdd897fc..04e757b1a 100644 --- a/MyBox/src/main/java/mara/mybox/image/ImageAnalyzeTools.java +++ b/MyBox/src/main/java/mara/mybox/image/ImageAnalyzeTools.java @@ -2,8 +2,7 @@ import java.awt.Color; import java.awt.image.BufferedImage; -import static mara.mybox.objects.AppVaribles.logger; - +import static mara.mybox.value.AppVaribles.logger; /** * @Author Mara @@ -14,8 +13,6 @@ */ public class ImageAnalyzeTools { - - public int[][] calculateHistogram(BufferedImage source) { try { int[] red = new int[256]; diff --git a/MyBox/src/main/java/mara/mybox/image/ImageBinary.java b/MyBox/src/main/java/mara/mybox/image/ImageBinary.java new file mode 100644 index 000000000..265d898b4 --- /dev/null +++ b/MyBox/src/main/java/mara/mybox/image/ImageBinary.java @@ -0,0 +1,256 @@ +package mara.mybox.image; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.io.File; +import javafx.embed.swing.SwingFXUtils; +import javafx.scene.image.Image; +import javax.imageio.ImageIO; +import static mara.mybox.value.AppVaribles.logger; + +/** + * @Author Mara + * @CreateDate 2019-2-15 + * @Version 1.0 + * @Description + * @License Apache License Version 2.0 + */ +public class ImageBinary extends PixelsOperation { + + protected boolean grayed, calculate; + + public ImageBinary() { + intPara1 = -1; + } + + public ImageBinary(BufferedImage image, OperationType operationType) { + this.image = image; + this.operationType = operationType; + intPara1 = -1; + } + + public ImageBinary(BufferedImage image, ImageScope scope, OperationType operationType) { + this.image = image; + this.scope = scope; + this.operationType = operationType; + intPara1 = -1; + ; + } + + public ImageBinary(BufferedImage image, int threshold) { + this.image = image; + this.scope = null; + this.operationType = OperationType.BlackOrWhite; + intPara1 = threshold; + } + + public ImageBinary(BufferedImage image, ImageScope scope, int threshold) { + this.image = image; + this.scope = scope; + this.operationType = OperationType.BlackOrWhite; + intPara1 = threshold; + } + + @Override + public BufferedImage operate() { + if (image == null || operationType == null + || operationType != OperationType.BlackOrWhite) { + return image; + } + grayed = false; + if (scope == null || scope.getScopeType() == ImageScope.ScopeType.All) { + if (!isDithering && !calculate && intPara1 < 0) { + return byteBinary(image); + } + image = ImageGray.byteGray(image); + grayed = true; + } + if (intPara1 < 0) { + if (grayed) { + intPara1 = OTSU(image); + } else { + intPara1 = calculateThreshold(image); + } + } + return operationImage(); + } + + @Override + protected Color operateColor(Color color) { + int gray; + if (grayed) { + gray = color.getRed(); + } else { + gray = ImageColor.RGB2GrayValue(color); + } + Color newColor; + if (gray < intPara1) { + newColor = Color.BLACK; + } else { + newColor = Color.WHITE; + } + return newColor; + } + + public static BufferedImage byteBinary(BufferedImage image) { + try { + int width = image.getWidth(); + int height = image.getHeight(); + BufferedImage binImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY); + Graphics2D graphics = binImage.createGraphics(); + graphics.drawImage(image, 0, 0, null); + return binImage; + } catch (Exception e) { + logger.error(e.toString()); + return image; + } + } + + public static BufferedImage intBinary(BufferedImage image) { + try { + int width = image.getWidth(); + int height = image.getHeight(); + BufferedImage greyImage = ImageGray.intGray(image); + int threshold = OTSU(greyImage); + int WHITE = Color.WHITE.getRGB(); + int BLACK = Color.BLACK.getRGB(); + BufferedImage binImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + int grey = new Color(greyImage.getRGB(x, y)).getRed(); + if (grey > threshold) { + binImage.setRGB(x, y, WHITE); + } else { + binImage.setRGB(x, y, BLACK); + } + } + } + return binImage; + } catch (Exception e) { + logger.error(e.toString()); + return image; + } + } + + public static Image binary(Image image) { + try { + BufferedImage bm = SwingFXUtils.fromFXImage(image, null); + bm = byteBinary(bm); + return SwingFXUtils.toFXImage(bm, null); + } catch (Exception e) { + logger.error(e.toString()); + return image; + } + } + + // OTSU algorithm: ICV=PA∗(MA−M)2+PB∗(MB−M)2 + // https://blog.csdn.net/taoyanbian1022/article/details/9030825 + // https://blog.csdn.net/liyuanbhu/article/details/49387483 + public static int OTSU(BufferedImage grayImage) { + try { + int width = grayImage.getWidth(); + int height = grayImage.getHeight(); + + int[] grayNumber = new int[256]; + for (int i = 0; i < width; i++) { + for (int j = 0; j < height; j++) { +// int r = 0xFF & grayImage.getRGB(i, j); + int gray = ImageColor.grayPixel2GrayValue(grayImage.getRGB(i, j)); + grayNumber[gray]++; + } + } + + float pixelTotal = width * height; + float[] grayRadio = new float[256]; + for (int i = 0; i < 256; i++) { + grayRadio[i] = grayNumber[i] / pixelTotal; + } + + float backgroundNumber, foregroundNumber, backgoundValue, foregroundValue; + float backgoundAverage, foregroundAverage, imageAverage, delta, deltaMax = 0; + int threshold = 0; + for (int gray = 0; gray < 256; gray++) { + backgroundNumber = 0; + foregroundNumber = 0; + backgoundValue = 0; + foregroundValue = 0; + for (int i = 0; i < 256; i++) { + if (i <= gray) { + backgroundNumber += grayRadio[i]; + backgoundValue += i * grayRadio[i]; + } else { + foregroundNumber += grayRadio[i]; + foregroundValue += i * grayRadio[i]; + } + } + + backgoundAverage = backgoundValue / backgroundNumber; + foregroundAverage = foregroundValue / foregroundNumber; + imageAverage = backgoundValue + foregroundValue; + + delta = backgroundNumber * (backgoundAverage - imageAverage) * (backgoundAverage - imageAverage) + + foregroundNumber * (foregroundAverage - imageAverage) * (foregroundAverage - imageAverage); + + if (delta > deltaMax) { + deltaMax = delta; + threshold = gray; + } + } +// logger.debug("threshold:" + threshold); + return threshold; + + } catch (Exception e) { + logger.error(e.toString()); + return -1; + } + } + + public static int calculateThreshold(File file) { + try { + BufferedImage bufferImage = ImageIO.read(file); + return OTSU(ImageGray.byteGray(bufferImage)); + } catch (Exception e) { + logger.error(e.toString()); + return -1; + } + } + + public static int calculateThreshold(BufferedImage image) { + try { + BufferedImage grayImage = ImageGray.byteGray(image); + return OTSU(grayImage); + } catch (Exception e) { + logger.error(e.toString()); + return -1; + } + } + + public static int calculateThreshold(Image image) { + try { + BufferedImage bm = SwingFXUtils.fromFXImage(image, null); + BufferedImage grey = byteBinary(bm); + return OTSU(bm); + } catch (Exception e) { + logger.error(e.toString()); + return -1; + } + } + + public boolean isGrayed() { + return grayed; + } + + public void setGrayed(boolean grayed) { + this.grayed = grayed; + } + + public boolean isCalculate() { + return calculate; + } + + public void setCalculate(boolean calculate) { + this.calculate = calculate; + } + +} diff --git a/MyBox/src/main/java/mara/mybox/image/ImageBlendTools.java b/MyBox/src/main/java/mara/mybox/image/ImageBlend.java similarity index 96% rename from MyBox/src/main/java/mara/mybox/image/ImageBlendTools.java rename to MyBox/src/main/java/mara/mybox/image/ImageBlend.java index 32fa52307..c9b847c53 100644 --- a/MyBox/src/main/java/mara/mybox/image/ImageBlendTools.java +++ b/MyBox/src/main/java/mara/mybox/image/ImageBlend.java @@ -3,7 +3,7 @@ import java.awt.Color; import java.awt.image.BufferedImage; import java.util.Random; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.logger; /** @@ -13,7 +13,7 @@ * @Description * @License Apache License Version 2.0 */ -public class ImageBlendTools { +public class ImageBlend { @@ -383,23 +383,23 @@ public static int blendColors(int forePixel, int bacckPixel, blue = Math.max(backColor.getBlue(), foreColor.getBlue()); break; case HUE: - float[] hA = ImageColorTools.pixel2HSB(forePixel); - float[] hB = ImageColorTools.pixel2HSB(bacckPixel); + float[] hA = ImageColor.pixel2HSB(forePixel); + float[] hB = ImageColor.pixel2HSB(bacckPixel); Color hColor = Color.getHSBColor(hA[0], hB[1], hB[2]); return hColor.getRGB(); case SATURATION: - float[] sA = ImageColorTools.pixel2HSB(forePixel); - float[] sB = ImageColorTools.pixel2HSB(bacckPixel); + float[] sA = ImageColor.pixel2HSB(forePixel); + float[] sB = ImageColor.pixel2HSB(bacckPixel); Color sColor = Color.getHSBColor(sB[0], sA[1], sB[2]); return sColor.getRGB(); case LUMINOSITY: - float[] bA = ImageColorTools.pixel2HSB(forePixel); - float[] bB = ImageColorTools.pixel2HSB(bacckPixel); + float[] bA = ImageColor.pixel2HSB(forePixel); + float[] bB = ImageColor.pixel2HSB(bacckPixel); Color newColor = Color.getHSBColor(bB[0], bB[1], bA[2]); return newColor.getRGB(); case COLOR: - float[] cA = ImageColorTools.pixel2HSB(forePixel); - float[] cB = ImageColorTools.pixel2HSB(bacckPixel); + float[] cA = ImageColor.pixel2HSB(forePixel); + float[] cB = ImageColor.pixel2HSB(bacckPixel); Color cColor = Color.getHSBColor(cA[0], cA[1], cB[2]); return cColor.getRGB(); default: diff --git a/MyBox/src/main/java/mara/mybox/image/ImageColor.java b/MyBox/src/main/java/mara/mybox/image/ImageColor.java new file mode 100644 index 000000000..ced509189 --- /dev/null +++ b/MyBox/src/main/java/mara/mybox/image/ImageColor.java @@ -0,0 +1,354 @@ +package mara.mybox.image; + +import java.awt.Color; +import java.awt.color.ColorSpace; + +/** + * @Author Mara + * @CreateDate 2018-6-4 16:07:27 + * @Description + * @License Apache License Version 2.0 + */ +public class ImageColor { + + public static int RGB2Pixel(int r, int g, int b, int a) { + return RGB2Pixel(new Color(r, g, b, a)); + } + + public static int RGB2Pixel(int r, int g, int b) { + return RGB2Pixel(r, g, b, 255); + } + + public static int RGB2Pixel(Color color) { + return color.getRGB(); + } + + public static Color pixel2RGB(int pixel) { + return new Color(pixel); + } + + public static float[] pixel2HSB(int pixel) { + Color rgb = pixel2RGB(pixel); + return Color.RGBtoHSB(rgb.getRed(), rgb.getGreen(), rgb.getBlue(), null); + } + + public static int RGB2GrayPixel(int r, int g, int b, int a) { + int gray = RGB2GrayValue(r, g, b); + return RGB2Pixel(gray, gray, gray, a); + } + + public static int pixel2GrayPixel(int pixel) { + Color c = pixel2RGB(pixel); + return RGB2GrayPixel(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); + } + + // https://en.wikipedia.org/wiki/HSL_and_HSV#Lightness + // https://en.wikipedia.org/wiki/Grayscale + // Simplest:I = ( R + G + B ) / 3 + // PAL和NTSC(Video) Y'UV and Y'IQ primaries Rec.601 : Y ′ = 0.299 R ′ + 0.587 G ′ + 0.114 B ′ + // HDTV(High Definiton TV) ITU-R primaries Rec.709: Y ′ = 0.2126 R ′ + 0.7152 G ′ + 0.0722 B ′ + // JDK internal: javafx.scene.paint.Color.grayscale() = 0.21 * red + 0.71 * green + 0.07 * blue + public static int RGB2GrayValue(int r, int g, int b) { + int gray = (2126 * r + 7152 * g + 722 * b) / 10000; + return gray; + } + + public static int RGB2GrayValue(Color color) { + return RGB2GrayValue(color.getRed(), color.getGreen(), color.getBlue()); + } + + public static int pixel2GrayValue(int pixel) { + Color c = new Color(pixel); + return RGB2GrayValue(c.getRed(), c.getGreen(), c.getBlue()); + } + + public static int grayPixel2GrayValue(int pixel) { + Color c = pixel2RGB(pixel); + return c.getRed(); + } + + public static Color RGB2Gray(Color color) { + int gray = RGB2GrayValue(color); + return new Color(gray, gray, gray, color.getAlpha()); + } + + public static String pixel2hex(int pixel) { + Color c = new Color(pixel); + return String.format("#%02X%02X%02X", c.getRed(), c.getGreen(), c.getBlue()); + } + + public static String getColorSpaceName(int colorType) { + switch (colorType) { + case ColorSpace.TYPE_XYZ: + return "XYZ"; + case ColorSpace.TYPE_Lab: + return "Lab"; + case ColorSpace.TYPE_Luv: + return "Luv"; + case ColorSpace.TYPE_YCbCr: + return "YCbCr"; + case ColorSpace.TYPE_Yxy: + return "Yxy"; + case ColorSpace.TYPE_RGB: + return "RGB"; + case ColorSpace.TYPE_GRAY: + return "GRAY"; + case ColorSpace.TYPE_HSV: + return "HSV"; + case ColorSpace.TYPE_HLS: + return "HLS"; + case ColorSpace.TYPE_CMYK: + return "CMYK"; + case ColorSpace.TYPE_CMY: + return "CMY"; + case ColorSpace.TYPE_2CLR: + return "2CLR"; + case ColorSpace.TYPE_3CLR: + return "3CLR"; + case ColorSpace.TYPE_4CLR: + return "4CLR"; + case ColorSpace.TYPE_5CLR: + return "5CLR"; + case ColorSpace.TYPE_6CLR: + return "6CLR"; + case ColorSpace.TYPE_7CLR: + return "CMY"; + case ColorSpace.TYPE_8CLR: + return "8CLR"; + case ColorSpace.TYPE_9CLR: + return "9CLR"; + case ColorSpace.TYPE_ACLR: + return "ACLR"; + case ColorSpace.TYPE_BCLR: + return "BCLR"; + case ColorSpace.TYPE_CCLR: + return "CCLR"; + case ColorSpace.TYPE_DCLR: + return "DCLR"; + case ColorSpace.TYPE_ECLR: + return "ECLR"; + case ColorSpace.TYPE_FCLR: + return "FCLR"; + case ColorSpace.CS_sRGB: + return "sRGB"; + case ColorSpace.CS_LINEAR_RGB: + return "LINEAR_RGB"; + case ColorSpace.CS_CIEXYZ: + return "CIEXYZ"; + case ColorSpace.CS_PYCC: + return "PYCC"; + case ColorSpace.CS_GRAY: + return "GRAY"; + default: + return "UNKOWN"; + + } + + } + + // 0.0-1.0 + public static float getHue(Color color) { + float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null); + return hsb[0]; + } + + // 0.0-1.0 + public static float getSaturation(Color color) { + float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null); + return hsb[1]; + } + + // 0.0-1.0 + public static float getBrightness(Color color) { + float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null); + return hsb[2]; + } + + public static float getBrightness(int pixel) { + Color color = new Color(pixel); + float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null); + return hsb[2]; + } + + public static float[] getHSB(Color color) { + return Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null); + } + + public static Color HSB2RGB(float h, float s, float b) { + return new Color(Color.HSBtoRGB(h, s, b)); + } + + // https://en.wikipedia.org/wiki/Color_difference + public static int calculateColorDistance(Color color1, Color color2) { + int v = calculateColorDistance2(color1, color2); + return (int) Math.round(Math.sqrt(v)); + } + + public static int calculateColorDistance2(Color color1, Color color2) { + int redDiff = color1.getRed() - color2.getRed(); + int greenDiff = color1.getGreen() - color2.getGreen(); + int blueDiff = color1.getBlue() - color2.getBlue(); + int v = (int) Math.round(2 * redDiff * redDiff + 4 * greenDiff * greenDiff + 3 * blueDiff * blueDiff); + return v; + } + + // distance2 = Math.pow(distance, 2) + public static boolean isColorMatch2(Color color1, Color color2, int distance2) { + if (color1.equals(color2)) { + return true; + } else if (distance2 == 0) { + return false; + } + return calculateColorDistance2(color1, color2) <= distance2; + } + + // distance: 0.0-1.0 + public static boolean isHueMatch(Color color1, Color color2, float distance) { + return Math.abs(getHue(color1) - getHue(color2)) <= distance; + } + + // distance: 0.0-1.0 + public static boolean isBrightnessMatch(Color color1, Color color2, float distance) { + return Math.abs(getBrightness(color1) - getBrightness(color2)) <= distance; + } + + // distance: 0.0-1.0 + public static boolean isSaturationMatch(Color color1, Color color2, float distance) { + return Math.abs(getSaturation(color1) - getSaturation(color2)) <= distance; + } + + // distance: 0-255 + public static boolean isRedMatch(Color color1, Color color2, int distance) { + return Math.abs(color1.getRed() - color2.getRed()) <= distance; + } + + // distance: 0-255 + public static boolean isGreenMatch(Color color1, Color color2, int distance) { + return Math.abs(color1.getGreen() - color2.getGreen()) <= distance; + } + + // distance: 0-255 + public static boolean isBlueMatch(Color color1, Color color2, int distance) { + return Math.abs(color1.getBlue() - color2.getBlue()) <= distance; + } + + // distance: 0-100 + public static boolean matchHue(Color color1, Color color2, + int distance, boolean excluded) { + boolean isMatch = ImageColor.isHueMatch(color1, color2, distance); + if (!excluded) { + return isMatch; + } else { + return !isMatch; + } + } + + // distance: 0.0-1.0 + public static boolean matchHue(Color color1, Color color2, + float distance, boolean excluded) { + boolean isMatch = ImageColor.isHueMatch(color1, color2, distance); + if (!excluded) { + return isMatch; + } else { + return !isMatch; + } + } + + public static Color scaleSaturate(Color color, float scale) { + float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null); + return Color.getHSBColor(hsb[0], hsb[1] * scale, hsb[2]); + } + + // https://stackoverflow.com/questions/21899824/java-convert-a-greyscale-and-sepia-version-of-an-image-with-bufferedimage/21900125#21900125 + public static Color pixel2Sepia(int pixel, int sepiaIntensity) { + return pixel2Sepia(pixel2RGB(pixel), sepiaIntensity); + } + + public static Color pixel2Sepia(Color color, int sepiaIntensity) { + int sepiaDepth = 20; + int gray = RGB2GrayValue(color); + int r = gray, g = gray, b = gray; + r = Math.min(r + (sepiaDepth * 2), 255); + g = Math.min(g + sepiaDepth, 255); + b = Math.min(Math.max(b - sepiaIntensity, 0), 255); + Color newColor = new Color(r, g, b, color.getAlpha()); + return newColor; + } + + public static Color thresholdingColor(Color inColor, + int threshold, int smallValue, int bigValue) { + int red, green, blue; + if (inColor.getRed() < threshold) { + red = smallValue; + } else { + red = bigValue; + } + if (inColor.getGreen() < threshold) { + green = smallValue; + } else { + green = bigValue; + } + if (inColor.getBlue() < threshold) { + blue = smallValue; + } else { + blue = bigValue; + } + Color newColor = new Color(red, green, blue, inColor.getAlpha()); + return newColor; + } + + public static javafx.scene.paint.Color converColor(Color color) { + return new javafx.scene.paint.Color( + color.getRed() / 255.0, color.getGreen() / 255.0, + color.getBlue() / 255.0, color.getAlpha() / 255.0); + } + + public static Color converColor(javafx.scene.paint.Color color) { + return new Color( + (int) (color.getRed() * 255), (int) (color.getGreen() * 255), + (int) (color.getBlue() * 255), (int) (color.getOpacity() * 255)); + } + + // https://en.wikipedia.org/wiki/YCbCr + public static int[] rgb2YCbCr(int r, int g, int b) { + int YCbCr[] = new int[3]; + YCbCr[0] = Math.round(0.299f * r + 0.587f * g + 0.114f * b); + YCbCr[0] = Math.max(Math.min(YCbCr[0], 255), 0); + YCbCr[1] = Math.round(128 - 0.168736f * r + 0.331264f * g + 0.5f * b); + YCbCr[1] = Math.max(Math.min(YCbCr[1], 255), 0); + YCbCr[2] = Math.round(128 + 0.5f * r + 0.418688f * g + 0.081312f * b); + YCbCr[2] = Math.max(Math.min(YCbCr[2], 255), 0); + return YCbCr; + } + + public static int[] rgb2YCbCr(Color color) { + return rgb2YCbCr(color.getRed(), color.getGreen(), color.getBlue()); + } + + public static int[] pixel2YCbCr(int pixel) { + return rgb2YCbCr(new Color(pixel)); + } + + public static int getLuma(Color color) { + int r = color.getRed(); + int g = color.getGreen(); + int b = color.getBlue(); + int Y = Math.round(0.299f * r + 0.587f * g + 0.114f * b); + return Math.max(Math.min(Y, 255), 0); + } + + public static Color YCbCr2rgb(int Y, int Cb, int Cr) { + int r = Math.round(Y + 1.402f * (Cr - 128)); + r = Math.max(Math.min(r, 255), 0); + int g = Math.round(Y - 0.344136f * (Cb - 128) - 0.714136f * (Cr - 128)); + g = Math.max(Math.min(g, 255), 0); + int b = Math.round(Y + 1.772f * (Cb - 128)); + b = Math.max(Math.min(b, 255), 0); + return new Color(r, g, b); + } + + public static int YCbCr2pixel(int Y, int Cb, int Cr) { + return YCbCr2rgb(Y, Cb, Cr).getRGB(); + } + +} diff --git a/MyBox/src/main/java/mara/mybox/image/ImageColorTools.java b/MyBox/src/main/java/mara/mybox/image/ImageColorTools.java deleted file mode 100644 index 13353f348..000000000 --- a/MyBox/src/main/java/mara/mybox/image/ImageColorTools.java +++ /dev/null @@ -1,232 +0,0 @@ -package mara.mybox.image; - -import java.awt.Color; -import java.awt.color.ColorSpace; - -import static mara.mybox.objects.AppVaribles.logger; - - -/** - * @Author Mara - * @CreateDate 2018-6-4 16:07:27 - * @Description - * @License Apache License Version 2.0 - */ -public class ImageColorTools { - - - - public static int RGB2Pixel(int r, int g, int b, int a) { - return RGB2Pixel(new Color(r, g, b, a)); - } - - public static int RGB2Pixel(int r, int g, int b) { - return RGB2Pixel(r, g, b, 255); - } - - public static int RGB2Pixel(Color color) { - return color.getRGB(); - } - - public static Color pixel2RGB(int pixel) { - return new Color(pixel); - } - - public static float[] pixel2HSB(int pixel) { - Color rgb = pixel2RGB(pixel); - return Color.RGBtoHSB(rgb.getRed(), rgb.getGreen(), rgb.getBlue(), null); - } - - public static int RGB2GrayPixel(int r, int g, int b, int a) { - int gray = RGB2GrayValue(r, g, b); - return ImageColorTools.RGB2Pixel(gray, gray, gray, a); - } - - public static int pixel2GrayPixel(int pixel) { - Color c = pixel2RGB(pixel); - return RGB2GrayPixel(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); - } - - // https://en.wikipedia.org/wiki/HSL_and_HSV#Lightness - // https://en.wikipedia.org/wiki/Grayscale - // Simplest:I = ( R + G + B ) / 3 - // PAL和NTSC(Video) Y'UV and Y'IQ primaries Rec.601 : Y ′ = 0.299 R ′ + 0.587 G ′ + 0.114 B ′ - // HDTV(High Definiton TV) ITU-R primaries Rec.709: Y ′ = 0.2126 R ′ + 0.7152 G ′ + 0.0722 B ′ - // JDK internal: javafx.scene.paint.Color.grayscale() = 0.21 * red + 0.71 * green + 0.07 * blue - public static int RGB2GrayValue(int r, int g, int b) { - int gray = (2126 * r + 7152 * g + 722 * b) / 10000; - return gray; - } - - public static int pixel2GrayValue(int pixel) { - Color c = new Color(pixel); - - return RGB2GrayValue(c.getRed(), c.getGreen(), c.getBlue()); - } - - public static int grayPixel2GrayValue(int pixel) { - Color c = pixel2RGB(pixel); - return c.getRed(); - } - - public static String getColorSpaceName(int colorType) { - switch (colorType) { - case ColorSpace.TYPE_XYZ: - return "XYZ"; - case ColorSpace.TYPE_Lab: - return "Lab"; - case ColorSpace.TYPE_Luv: - return "Luv"; - case ColorSpace.TYPE_YCbCr: - return "YCbCr"; - case ColorSpace.TYPE_Yxy: - return "Yxy"; - case ColorSpace.TYPE_RGB: - return "RGB"; - case ColorSpace.TYPE_GRAY: - return "GRAY"; - case ColorSpace.TYPE_HSV: - return "HSV"; - case ColorSpace.TYPE_HLS: - return "HLS"; - case ColorSpace.TYPE_CMYK: - return "CMYK"; - case ColorSpace.TYPE_CMY: - return "CMY"; - case ColorSpace.TYPE_2CLR: - return "2CLR"; - case ColorSpace.TYPE_3CLR: - return "3CLR"; - case ColorSpace.TYPE_4CLR: - return "4CLR"; - case ColorSpace.TYPE_5CLR: - return "5CLR"; - case ColorSpace.TYPE_6CLR: - return "6CLR"; - case ColorSpace.TYPE_7CLR: - return "CMY"; - case ColorSpace.TYPE_8CLR: - return "8CLR"; - case ColorSpace.TYPE_9CLR: - return "9CLR"; - case ColorSpace.TYPE_ACLR: - return "ACLR"; - case ColorSpace.TYPE_BCLR: - return "BCLR"; - case ColorSpace.TYPE_CCLR: - return "CCLR"; - case ColorSpace.TYPE_DCLR: - return "DCLR"; - case ColorSpace.TYPE_ECLR: - return "ECLR"; - case ColorSpace.TYPE_FCLR: - return "FCLR"; - case ColorSpace.CS_sRGB: - return "sRGB"; - case ColorSpace.CS_LINEAR_RGB: - return "LINEAR_RGB"; - case ColorSpace.CS_CIEXYZ: - return "CIEXYZ"; - case ColorSpace.CS_PYCC: - return "PYCC"; - case ColorSpace.CS_GRAY: - return "GRAY"; - default: - return "UNKOWN"; - - } - - } - - // https://en.wikipedia.org/wiki/Color_difference - public static double calculateColorDistance(Color color1, Color color2) { - double v = 2 * Math.pow(color1.getRed() - color2.getRed(), 2) - + 4 * Math.pow(color1.getGreen() - color2.getGreen(), 2) - + 3 * Math.pow(color1.getBlue() - color2.getBlue(), 2); - return Math.sqrt(v); - } - - public static double calculateColorDistance2(Color color1, Color color2) { - double v = 2 * Math.pow(color1.getRed() - color2.getRed(), 2) - + 4 * Math.pow(color1.getGreen() - color2.getGreen(), 2) - + 3 * Math.pow(color1.getBlue() - color2.getBlue(), 2); - return v; - } - - public static boolean isColorMatch(Color color1, Color color2, int distance) { - if (color1 == color2) { - return true; - } else if (distance == 0) { - return false; - } - return calculateColorDistance2(color1, color2) <= Math.pow(distance, 2); - } - - public static boolean isHueMatch(Color color1, Color color2, int distance) { - return Math.abs(getHue(color1) - getHue(color2)) <= distance; - } - - public static boolean matchColor(Color color1, Color color2, - int distance, boolean isColor, boolean excluded) { - boolean isMatch; - if (isColor) { - isMatch = ImageColorTools.isColorMatch(color1, color2, distance); - } else { - isMatch = ImageColorTools.isHueMatch(color1, color2, distance); - } - if (!excluded) { - return isMatch; - } else { - return !isMatch; - } - } - - public static boolean matchColor(Color color1, Color color2, - int distance, boolean excluded) { - boolean isMatch = ImageColorTools.isColorMatch(color1, color2, distance); - if (!excluded) { - return isMatch; - } else { - return !isMatch; - } - } - - public static boolean matchHue(Color color1, Color color2, - int distance, boolean excluded) { - boolean isMatch = ImageColorTools.isHueMatch(color1, color2, distance); - if (!excluded) { - return isMatch; - } else { - return !isMatch; - } - } - - public static int getHue(Color color) { - float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null); - return (int) (hsb[0] * 360); - } - - public static float getSaturate(Color color) { - float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null); - return hsb[1]; - } - - public static Color scaleSaturate(Color color, float scale) { - float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null); - return Color.getHSBColor(hsb[0], hsb[1] * scale, hsb[2]); - } - - // https://stackoverflow.com/questions/21899824/java-convert-a-greyscale-and-sepia-version-of-an-image-with-bufferedimage/21900125#21900125 - public static Color pixel2Sepia(int pixel, int sepiaIntensity) { - int sepiaDepth = 20; - int gray = pixel2GrayValue(pixel); - int r = gray, g = gray, b = gray; - r = Math.min(r + (sepiaDepth * 2), 255); - g = Math.min(g + sepiaDepth, 255); - b = Math.min(Math.max(b - sepiaIntensity, 0), 255); - Color color = new Color(pixel, true); - Color newColor = new Color(r, g, b, color.getAlpha()); - return newColor; - } - -} diff --git a/MyBox/src/main/java/mara/mybox/image/ImageContrast.java b/MyBox/src/main/java/mara/mybox/image/ImageContrast.java new file mode 100644 index 000000000..2082e73fd --- /dev/null +++ b/MyBox/src/main/java/mara/mybox/image/ImageContrast.java @@ -0,0 +1,263 @@ +package mara.mybox.image; + +import java.awt.Color; +import java.awt.image.BufferedImage; +import java.io.File; +import javax.imageio.ImageIO; +import static mara.mybox.value.AppVaribles.logger; + +/** + * @Author Mara + * @CreateDate 2019-2-17 + * @Version 1.0 + * @Description + * @License Apache License Version 2.0 + */ +public class ImageContrast extends PixelsOperation { + + protected ContrastAlgorithm algorithm; + + public static enum ContrastAlgorithm { + Gray_Histogram_Equalization, + Gray_Histogram_Stretching, + Gray_Histogram_Shifting, + Luma_Histogram_Equalization, + HSB_Histogram_Equalization, + Adaptive_Histogram_Equalization + } + + public ImageContrast() { + this.operationType = OperationType.Contrast; + } + + public ImageContrast(BufferedImage image) { + this.operationType = OperationType.Contrast; + this.image = image; + } + + public ImageContrast(BufferedImage image, ContrastAlgorithm algorithm) { + this.operationType = OperationType.Contrast; + this.image = image; + this.algorithm = algorithm; + } + + public ImageContrast(BufferedImage image, ImageScope scope, ContrastAlgorithm algorithm) { + this.operationType = OperationType.Contrast; + this.image = image; + this.scope = scope; + this.algorithm = algorithm; + } + + @Override + public BufferedImage operate() { + if (image == null || operationType != OperationType.Contrast || null == algorithm) { + return image; + } + switch (algorithm) { + case Gray_Histogram_Equalization: + return grayHistogramEqualization(image); + case Gray_Histogram_Shifting: + return grayHistogramShifting(image, intPara1); + case Gray_Histogram_Stretching: + return grayHistogramStretching(image, intPara1, intPara2); + case Luma_Histogram_Equalization: + return lumaHistogramEqualization(image); + case HSB_Histogram_Equalization: + return brightnessHistogramEqualization(image); + default: + return image; + } + + } + + public static int[] grayHistogram(BufferedImage greyImage) { + if (greyImage == null) { + return null; + } + int width = greyImage.getWidth(); + int height = greyImage.getHeight(); + int[] greyHistogram = new int[256]; + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + int grey = new Color(greyImage.getRGB(x, y)).getRed(); + greyHistogram[grey]++; + } + } + return greyHistogram; + } + + // https://en.wikipedia.org/wiki/Histogram_equalization + public static BufferedImage grayHistogramEqualization(BufferedImage image) { + if (image == null) { + return null; + } + BufferedImage grayImage = image; + if (image.getType() != BufferedImage.TYPE_BYTE_GRAY) { + grayImage = ImageGray.byteGray(image); + } + int width = grayImage.getWidth(); + int height = grayImage.getHeight(); + int[] greyHistogram = grayHistogram(grayImage); + + float nf = 255.0f / (width * height); + int cumulative = 0; + int[] lookUpTable = new int[256]; + for (int i = 0; i < 256; i++) { + cumulative += greyHistogram[i]; + lookUpTable[i] = Math.round(cumulative * nf); + } + + BufferedImage target = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + int grey = new Color(grayImage.getRGB(x, y)).getRed(); + grey = lookUpTable[grey]; + target.setRGB(x, y, ImageColor.RGB2Pixel(grey, grey, grey)); + } + } + return target; + } + + public static BufferedImage grayHistogramShifting(BufferedImage image, int offset) { + if (image == null) { + return null; + } + BufferedImage grayImage = image; + if (image.getType() != BufferedImage.TYPE_BYTE_GRAY) { + grayImage = ImageGray.byteGray(image); + } + int width = grayImage.getWidth(); + int height = grayImage.getHeight(); + BufferedImage target = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + int grey = new Color(grayImage.getRGB(x, y)).getRed(); + grey = Math.max(Math.min(grey + offset, 255), 0); + target.setRGB(x, y, ImageColor.RGB2Pixel(grey, grey, grey)); + } + } + return target; + } + + public static BufferedImage grayHistogramStretching(BufferedImage image, + int leftThreshold, int rightThreshold) { + if (image == null || leftThreshold < 0 || rightThreshold < 0) { + return null; + } + BufferedImage grayImage = image; + if (image.getType() != BufferedImage.TYPE_BYTE_GRAY) { + grayImage = ImageGray.byteGray(image); + } + int width = grayImage.getWidth(); + int height = grayImage.getHeight(); + int min = 0, max = 0; + int[] greyHistogram = grayHistogram(image); + for (int i = 0; i < 256; i++) { + if (greyHistogram[i] >= leftThreshold) { + min = i; + break; + } + } + for (int i = 255; i >= 0; i--) { + if (greyHistogram[i] >= rightThreshold) { + max = i; + break; + } + } + if (min == 0 && max == 255) { + return grayImage; + } + BufferedImage target = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY); + float scale = 255.0f / (max - min); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + int grey = new Color(grayImage.getRGB(x, y)).getRed(); + if (grey <= min) { + grey = 0; + } else if (grey >= max) { + grey = 255; + } else { + grey = (int) ((grey - min) * scale); + } + target.setRGB(x, y, ImageColor.RGB2Pixel(grey, grey, grey)); + } + } + return target; + } + + public static BufferedImage brightnessHistogramEqualization(BufferedImage colorImage) { + if (colorImage == null) { + return null; + } + int width = colorImage.getWidth(); + int height = colorImage.getHeight(); + int[] brightnessHistogram = new int[101]; + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + int brightness = Math.round(ImageColor.getBrightness(new Color(colorImage.getRGB(x, y))) * 100); + brightnessHistogram[brightness]++; + } + } + + float nf = 100.0f / (width * height); + int cumulative = 0; + int[] lookUpTable = new int[101]; + for (int i = 0; i < 101; i++) { + cumulative += brightnessHistogram[i]; + lookUpTable[i] = Math.round(cumulative * nf); + } + + BufferedImage target = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + float[] hsb = ImageColor.getHSB(new Color(colorImage.getRGB(x, y))); + int brightness = Math.round(hsb[2] * 100); + brightness = lookUpTable[brightness]; + target.setRGB(x, y, Color.HSBtoRGB(hsb[0], hsb[1], brightness / 100.0f)); + } + } + return target; + } + + public static BufferedImage lumaHistogramEqualization(BufferedImage colorImage1) { +// if (colorImage == null) { +// return null; +// } + try { + BufferedImage colorImage = ImageIO.read(new File("D:\\tmp\\测试文件\\普通图片\\直方图\\f1.jpeg")); + + int width = colorImage.getWidth(); + int height = colorImage.getHeight(); + logger.debug(width); +// int[] lumaHistogram = new int[256]; +// for (int y = 0; y < height; y++) { +// for (int x = 0; x < width; x++) { +// int luma = ImageColor.getLuma(new Color(colorImage.getRGB(x, y))); +// lumaHistogram[luma]++; +// } +// } +// +// float nf = 255.0f / (width * height); +// int cumulative = 0; +// int[] lookUpTable = new int[256]; +// for (int i = 0; i < 256; i++) { +// cumulative += lumaHistogram[i]; +// lookUpTable[i] = Math.round(cumulative * nf); +// } + + BufferedImage target = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + int[] YCbCr = ImageColor.pixel2YCbCr(colorImage.getRGB(x, y)); + int luma = YCbCr[0]; +// luma = lookUpTable[luma]; + target.setRGB(x, y, ImageColor.YCbCr2pixel(luma, YCbCr[1], YCbCr[2])); + } + } + return target; + } catch (Exception e) { + return colorImage1; + } + } + +} diff --git a/MyBox/src/main/java/mara/mybox/image/ImageConvertTools.java b/MyBox/src/main/java/mara/mybox/image/ImageConvert.java similarity index 97% rename from MyBox/src/main/java/mara/mybox/image/ImageConvertTools.java rename to MyBox/src/main/java/mara/mybox/image/ImageConvert.java index ccce460de..b4be5bbac 100644 --- a/MyBox/src/main/java/mara/mybox/image/ImageConvertTools.java +++ b/MyBox/src/main/java/mara/mybox/image/ImageConvert.java @@ -1,6 +1,6 @@ package mara.mybox.image; -import mara.mybox.fxml.FxmlImageTools; +import mara.mybox.fxml.image.ImageTools; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Font; @@ -15,13 +15,13 @@ import java.util.ArrayList; import java.util.List; import javafx.embed.swing.SwingFXUtils; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.CommonValues; -import static mara.mybox.objects.CommonValues.AlphaColor; -import mara.mybox.objects.ImageCombine; -import mara.mybox.objects.ImageCombine.CombineSizeType; -import mara.mybox.objects.ImageInformation; -import static mara.mybox.objects.AppVaribles.logger; +import mara.mybox.value.AppVaribles; +import mara.mybox.value.CommonValues; +import static mara.mybox.value.CommonValues.AlphaColor; +import mara.mybox.data.ImageCombine; +import mara.mybox.data.ImageCombine.CombineSizeType; +import mara.mybox.data.ImageInformation; +import static mara.mybox.value.AppVaribles.logger; /** * @Author Mara @@ -29,7 +29,7 @@ * @Version 1.0 * @License Apache License Version 2.0 */ -public class ImageConvertTools { +public class ImageConvert { public static class Direction { @@ -63,7 +63,7 @@ public static boolean hasAlpha(BufferedImage source) { public static BufferedImage checkAlpha(BufferedImage source, String targetFormat) { if (targetFormat != null && CommonValues.NoAlphaImages.contains(targetFormat.toLowerCase())) { - return ImageConvertTools.clearAlpha(source); + return ImageConvert.clearAlpha(source); } else { return source; } @@ -74,9 +74,9 @@ public static BufferedImage clearAlpha(BufferedImage source) { return source; } if (AppVaribles.isAlphaAsBlack()) { - return ImageConvertTools.replaceAlphaAsBlack(source); + return ImageConvert.replaceAlphaAsBlack(source); } else { - return ImageConvertTools.replaceAlphaAsWhite(source); + return ImageConvert.replaceAlphaAsWhite(source); } } @@ -498,7 +498,7 @@ public static javafx.scene.image.Image combineSingleColumn(ImageCombine imageCom totalHeight = y + imageCombine.getMarginsValue() - imageCombine.getIntervalValue(); javafx.scene.image.Image newImage = combineImages(images, totalWidth, totalHeight, - FxmlImageTools.colorConvert(imageCombine.getBgColor()), + ImageTools.colorConvert(imageCombine.getBgColor()), xs, ys, widths, heights, imageCombine.getTotalWidthValue(), imageCombine.getTotalHeightValue(), careTotal && (sizeType == CombineSizeType.TotalWidth), @@ -585,7 +585,7 @@ public static javafx.scene.image.Image combineSingleRow(ImageCombine imageCombin } javafx.scene.image.Image newImage = combineImages(images, totalWidth, totalHeight, - FxmlImageTools.colorConvert(imageCombine.getBgColor()), + ImageTools.colorConvert(imageCombine.getBgColor()), xs, ys, widths, heights, imageCombine.getTotalWidthValue(), imageCombine.getTotalHeightValue(), careTotal && (sizeType == CombineSizeType.TotalWidth), diff --git a/MyBox/src/main/java/mara/mybox/image/ImageConvolution.java b/MyBox/src/main/java/mara/mybox/image/ImageConvolution.java new file mode 100644 index 000000000..3988c8c12 --- /dev/null +++ b/MyBox/src/main/java/mara/mybox/image/ImageConvolution.java @@ -0,0 +1,304 @@ +package mara.mybox.image; + +import java.awt.Color; +import java.awt.image.BufferedImage; +import java.awt.image.ConvolveOp; +import java.awt.image.Kernel; +import mara.mybox.data.ConvolutionKernel; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.tools.ValueTools; + +/** + * @Author Mara + * @CreateDate 2018-11-10 19:35:49 + * @Version 1.0 + * @Description + * @License Apache License Version 2.0 + */ +public class ImageConvolution extends PixelsOperation { + + protected ConvolutionKernel kernel; + protected int matrixWidth, matrixHeight, edge_op, radiusX, radiusY, maxX, maxY; + protected boolean keepOpacity, isEmboss, isGray; + protected float[][] matrix; + + public ImageConvolution() { + this.operationType = OperationType.Convolution; + } + + public ImageConvolution(BufferedImage image) { + this.image = image; + this.operationType = OperationType.Convolution; + this.scope = null; + } + + public ImageConvolution(BufferedImage image, ImageScope scope) { + this.image = image; + this.operationType = OperationType.Convolution; + this.scope = scope; + } + + public ImageConvolution(BufferedImage image, ConvolutionKernel kernel) { + this.image = image; + this.operationType = OperationType.Convolution; + this.scope = null; + init(kernel); + } + + public ImageConvolution(BufferedImage image, ImageScope scope, ConvolutionKernel kernel) { + this.image = image; + this.operationType = OperationType.Convolution; + this.scope = scope; + init(kernel); + } + + private void init(ConvolutionKernel kernel) { + setKernel(kernel); + } + + public void setKernel(ConvolutionKernel kernel) { + this.kernel = kernel; + matrix = kernel.getMatrix(); + matrixWidth = matrix[0].length; + matrixHeight = matrix.length; + edge_op = kernel.getEdge(); + radiusX = matrixWidth / 2; + radiusY = matrixHeight / 2; + maxX = image.getWidth() - 1; + maxY = image.getHeight() - 1; + isEmboss = (kernel.getType() == ConvolutionKernel.Convolution_Type.EMBOSS); + isGray = (kernel.getGray() > 0); + keepOpacity = (kernel.getType() != ConvolutionKernel.Convolution_Type.EMBOSS + && kernel.getType() != ConvolutionKernel.Convolution_Type.EDGE_DETECTION); + } + + @Override + public BufferedImage operate() { + if (image == null || kernel == null || kernel.getMatrix() == null) { + return image; + } + return super.operate(); + } + + @Override + public BufferedImage operationImage() { + if (image == null || operationType == null) { + return image; + } + if (scope == null || scope.getScopeType() == ImageScope.ScopeType.All) { + return applyConvolution(image, kernel); + + } + return super.operationImage(); + } + + @Override + protected void operatePixel(BufferedImage target, Color color, int x, int y) { + int pixel = image.getRGB(x, y); + if (x < radiusX || x + radiusX > maxX + || y < radiusY || y + radiusY > maxY) { + if (edge_op == ConvolutionKernel.Edge_Op.COPY) { + target.setRGB(x, y, pixel); + return; + } + } + Color newColor = applyConvolution(x, y); + if (isEmboss) { + int v = 128, red, blue, green; + red = Math.min(Math.max(newColor.getRed() + v, 0), 255); + green = Math.min(Math.max(newColor.getGreen() + v, 0), 255); + blue = Math.min(Math.max(newColor.getBlue() + v, 0), 255); + newColor = new Color(red, green, blue, newColor.getAlpha()); + if (isGray) { + newColor = ImageColor.RGB2Gray(newColor); + } + } + target.setRGB(x, y, newColor.getRGB()); + } + + public Color applyConvolution(int x, int y) { + try { + int red = 0, green = 0, blue = 0, opacity = 0; + int convolveX, convolveY; + for (int matrixY = 0; matrixY < matrixHeight; matrixY++) { + for (int matrixX = 0; matrixX < matrixWidth; matrixX++) { + convolveX = x - radiusX + matrixX; + convolveY = y - radiusY + matrixY; + if (convolveX < 0 || convolveX > maxX || convolveY < 0 || convolveY > maxY) { + if (edge_op == ConvolutionKernel.Edge_Op.MOD) { + convolveX = (convolveX + imageWidth) % imageWidth; + convolveY = (convolveY + imageHeight) % imageHeight; + } else { + continue; // Fill_zero + } + } + Color color = new Color(image.getRGB(convolveX, convolveY)); + red += color.getRed() * matrix[matrixY][matrixX]; + green += color.getGreen() * matrix[matrixY][matrixX]; + blue += color.getBlue() * matrix[matrixY][matrixX]; + if (keepOpacity) { + opacity += color.getAlpha() * matrix[matrixY][matrixX]; + } + } + } + red = Math.min(Math.max(red, 0), 255); + green = Math.min(Math.max(green, 0), 255); + blue = Math.min(Math.max(blue, 0), 255); + if (keepOpacity) { + opacity = Math.min(Math.max(opacity, 0), 255); + } else { + opacity = 255; + } + Color color = new Color(red, green, blue, opacity); + return color; + } catch (Exception e) { + logger.error(e.toString()); + return null; + } + + } + + public static BufferedImage applyConvolution(BufferedImage source, + ConvolutionKernel convolutionKernel) { + BufferedImage clearedSource; + int type = convolutionKernel.getType(); + if (type == ConvolutionKernel.Convolution_Type.EDGE_DETECTION + || type == ConvolutionKernel.Convolution_Type.EMBOSS) { + clearedSource = ImageConvert.clearAlpha(source); + } else { + clearedSource = source; + } + float[] k = ValueTools.matrix2Array(convolutionKernel.getMatrix()); + if (k == null) { + return clearedSource; + } + int w = convolutionKernel.getWidth(); + int h = convolutionKernel.getHeight(); + Kernel kernel = new Kernel(w, h, k); + ConvolveOp imageOp; + if (convolutionKernel.getEdge() == ConvolutionKernel.Edge_Op.COPY) { + imageOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null); + } else { + imageOp = new ConvolveOp(kernel, ConvolveOp.EDGE_ZERO_FILL, null); + } + BufferedImage target = applyConvolveOp(clearedSource, imageOp); + if (type == ConvolutionKernel.Convolution_Type.EMBOSS) { + PixelsOperation pixelsOperation = new PixelsOperation(target, null, + OperationType.RGB, ColorActionType.Increase); + pixelsOperation.setIntPara1(128); + target = pixelsOperation.operate(); + if (convolutionKernel.getGray() > 0) { + target = ImageGray.byteGray(target); + } + } + return target; + } + + public static BufferedImage applyConvolveOp(BufferedImage source, ConvolveOp imageOp) { + if (source == null || imageOp == null) { + return source; + } + int width = source.getWidth(); + int height = source.getHeight(); + int imageType = source.getType(); + if (imageType == BufferedImage.TYPE_CUSTOM) { + imageType = BufferedImage.TYPE_INT_ARGB; + } + BufferedImage target = new BufferedImage(width, height, imageType); + imageOp.filter(source, target); + return target; + } + + public ConvolutionKernel getKernel() { + return kernel; + } + + public int getMatrixWidth() { + return matrixWidth; + } + + public void setMatrixWidth(int matrixWidth) { + this.matrixWidth = matrixWidth; + } + + public int getMatrixHeight() { + return matrixHeight; + } + + public void setMatrixHeight(int matrixHeight) { + this.matrixHeight = matrixHeight; + } + + public int getEdge_op() { + return edge_op; + } + + public void setEdge_op(int edge_op) { + this.edge_op = edge_op; + } + + public int getRadiusX() { + return radiusX; + } + + public void setRadiusX(int radiusX) { + this.radiusX = radiusX; + } + + public int getRadiusY() { + return radiusY; + } + + public void setRadiusY(int radiusY) { + this.radiusY = radiusY; + } + + public int getMaxX() { + return maxX; + } + + public void setMaxX(int maxX) { + this.maxX = maxX; + } + + public int getMaxY() { + return maxY; + } + + public void setMaxY(int maxY) { + this.maxY = maxY; + } + + public boolean isKeepOpacity() { + return keepOpacity; + } + + public void setKeepOpacity(boolean keepOpacity) { + this.keepOpacity = keepOpacity; + } + + public boolean isIsEmboss() { + return isEmboss; + } + + public void setIsEmboss(boolean isEmboss) { + this.isEmboss = isEmboss; + } + + public boolean isIsGray() { + return isGray; + } + + public void setIsGray(boolean isGray) { + this.isGray = isGray; + } + + public float[][] getMatrix() { + return matrix; + } + + public void setMatrix(float[][] matrix) { + this.matrix = matrix; + } + +} diff --git a/MyBox/src/main/java/mara/mybox/image/ImageEffectTools.java b/MyBox/src/main/java/mara/mybox/image/ImageEffectTools.java deleted file mode 100644 index 60f2de04a..000000000 --- a/MyBox/src/main/java/mara/mybox/image/ImageEffectTools.java +++ /dev/null @@ -1,219 +0,0 @@ -package mara.mybox.image; - -import java.awt.Color; -import java.awt.image.BufferedImage; -import java.awt.image.BufferedImageOp; -import java.awt.image.ConvolveOp; -import java.awt.image.Kernel; -import java.awt.image.LookupOp; -import java.awt.image.ShortLookupTable; -import static mara.mybox.image.ImageConvertTools.clearAlpha; -import mara.mybox.objects.ConvolutionKernel; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.tools.ValueTools; - -/** - * @Author Mara - * @CreateDate 2018-11-10 20:02:44 - * @Version 1.0 - * @Description - * @License Apache License Version 2.0 - */ -public class ImageEffectTools { - - public static BufferedImage applyMatrix(BufferedImage source, float[][] matrix) { - return applyMatrix(source, matrix, ConvolutionKernel.Edge_Op.FILL_ZERO); - } - - public static BufferedImage applyMatrix(BufferedImage source, float[][] matrix, int edge_op) { - if (source == null || matrix == null) { - return source; - } - float[] a = ValueTools.matrix2Array(matrix); - Kernel k = new Kernel(matrix.length, matrix[0].length, a); - return applyKernel(source, k, edge_op); - } - - public static BufferedImage applyKernel(BufferedImage source, Kernel filter) { - return applyKernel(source, filter, ConvolutionKernel.Edge_Op.FILL_ZERO); - } - - public static BufferedImage applyKernel(BufferedImage source, Kernel filter, int edge_op) { - if (source == null || filter == null) { - return source; - } - ConvolveOp imageOp; - if (edge_op == ConvolutionKernel.Edge_Op.COPY) { - imageOp = new ConvolveOp(filter, ConvolveOp.EDGE_NO_OP, null); - } else { - imageOp = new ConvolveOp(filter, ConvolveOp.EDGE_ZERO_FILL, null); - } - return applyConvolveOp(source, imageOp); - } - - public static BufferedImage applyConvolveOp(BufferedImage source, ConvolveOp imageOp) { - if (source == null || imageOp == null) { - return source; - } - int width = source.getWidth(); - int height = source.getHeight(); - int imageType = source.getType(); - if (imageType == BufferedImage.TYPE_CUSTOM) { - imageType = BufferedImage.TYPE_INT_ARGB; - } - BufferedImage target = new BufferedImage(width, height, imageType); - imageOp.filter(source, target); - return target; - } - - public static BufferedImage applyConvolution(BufferedImage source, ConvolutionKernel convolutionKernel) { - BufferedImage clearedSource; - int type = convolutionKernel.getType(); - if (type == ConvolutionKernel.Convolution_Type.EDGE_DETECTION - || type == ConvolutionKernel.Convolution_Type.EMBOSS) { - clearedSource = clearAlpha(source); - } else { - clearedSource = source; - } - float[] k = ValueTools.matrix2Array(convolutionKernel.getMatrix()); - if (k == null) { - return clearedSource; - } - int w = convolutionKernel.getWidth(); - int h = convolutionKernel.getHeight(); - Kernel kernel = new Kernel(w, h, k); - ConvolveOp imageOp; - if (convolutionKernel.getEdge() == ConvolutionKernel.Edge_Op.COPY) { - imageOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null); - } else { - imageOp = new ConvolveOp(kernel, ConvolveOp.EDGE_ZERO_FILL, null); - } - BufferedImage target = applyConvolveOp(clearedSource, imageOp); - if (type == ConvolutionKernel.Convolution_Type.EMBOSS) { - target = ImageAdjustColorTools.changeRGB(target, 128); - if (convolutionKernel.getGray() > 0) { - target = ImageGrayTools.color2Gray(target); - } - } - return target; - } - - public static BufferedImage applyMatrixLocal(BufferedImage source, float[][] matrix, int edge_op) { - if (source == null || matrix == null || matrix.length == 0) { - return source; - } - try { - int imageWidth = source.getWidth(); - int imageHeight = source.getHeight(); - int imageType = source.getType(); - if (imageType == BufferedImage.TYPE_CUSTOM) { - imageType = BufferedImage.TYPE_INT_ARGB; - } - int matrixWidth = matrix[0].length; - int matrixHeight = matrix.length; - BufferedImage target = new BufferedImage(imageWidth, imageHeight, imageType); - int convolveX, convolveY, radiusX = matrixWidth / 2, radiusY = matrixHeight / 2, - maxX = imageWidth - 1, maxY = imageHeight - 1; - for (int pixelY = 0; pixelY < imageHeight; pixelY++) { - for (int pixelX = 0; pixelX < imageWidth; pixelX++) { - if (pixelX < radiusX || pixelX + radiusX > maxX - || pixelY < radiusY || pixelY + radiusY > maxY) { - if (edge_op == ConvolutionKernel.Edge_Op.COPY) { - target.setRGB(pixelX, pixelY, source.getRGB(pixelX, pixelY)); - continue; - } - } - double red = 0.0, green = 0.0, blue = 0.0, alpha = 0.0; - for (int matrixY = 0; matrixY < matrixHeight; matrixY++) { - for (int matrixX = 0; matrixX < matrixWidth; matrixX++) { - convolveX = pixelX - radiusX + matrixX; - convolveY = pixelY - radiusY + matrixY; - if (convolveX < 0 || convolveX > maxX || convolveY < 0 || convolveY > maxY) { - if (edge_op == ConvolutionKernel.Edge_Op.MOD) { - convolveX = (convolveX + imageWidth) % imageWidth; - convolveY = (convolveY + imageHeight) % imageHeight; - } else { - continue; // Fill_zero - } - } - Color color = new Color(source.getRGB(convolveX, convolveY), true); - red += color.getRed() * matrix[matrixY][matrixX]; - green += color.getGreen() * matrix[matrixY][matrixX]; - blue += color.getBlue() * matrix[matrixY][matrixX]; - alpha += color.getAlpha() * matrix[matrixY][matrixX]; - } - } - red = Math.min(Math.max(red, 0), 255); - green = Math.min(Math.max(green, 0), 255); - blue = Math.min(Math.max(blue, 0), 255); - alpha = Math.min(Math.max(alpha, 0), 255); - Color newColor = new Color((int) red, (int) green, (int) blue, (int) alpha); - target.setRGB(pixelX, pixelY, newColor.getRGB()); - } - } - return target; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - - } - - // https://www.javaworld.com/article/2076764/java-se/image-processing-with-java-2d.html?page=2 - public static BufferedImage thresholding(BufferedImage source, int threshold, int smallValue, int bigValue) { - try { - short[] thresholdArray = new short[256]; - for (int i = 0; i < 256; i++) { - if (i < threshold) { - thresholdArray[i] = (short) smallValue; - } else { - thresholdArray[i] = (short) bigValue; - } - } - BufferedImageOp thresholdingOp = new LookupOp(new ShortLookupTable(0, thresholdArray), null); - return thresholdingOp.filter(source, null); - } catch (Exception e) { - logger.debug(e.toString()); - return null; - } - } - - // https://www.javaworld.com/article/2076764/java-se/image-processing-with-java-2d.html?page=1 - public static BufferedImage posterizing(BufferedImage source, int size) { - try { - short[] posterize = new short[256]; - for (int i = 0; i < 256; i++) { - posterize[i] = (short) (i - (i % size)); - } - BufferedImageOp posterizeOp = new LookupOp(new ShortLookupTable(0, posterize), null); - return posterizeOp.filter(source, null); - } catch (Exception e) { - logger.debug(e.toString()); - return null; - } - } - - public static BufferedImage sepiaImage(BufferedImage source, int sepiaIntensity) { - try { - int width = source.getWidth(); - int height = source.getHeight(); - int imageType = source.getType(); - if (imageType == BufferedImage.TYPE_CUSTOM) { - imageType = BufferedImage.TYPE_INT_ARGB; - } - BufferedImage target = new BufferedImage(width, height, imageType); - for (int j = 0; j < height; j++) { - for (int i = 0; i < width; i++) { - int pixel = source.getRGB(i, j); - Color newColor = ImageColorTools.pixel2Sepia(pixel, sepiaIntensity); - target.setRGB(i, j, newColor.getRGB()); - } - } - return target; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - } - -} diff --git a/MyBox/src/main/java/mara/mybox/image/ImageFilterTools.java b/MyBox/src/main/java/mara/mybox/image/ImageFilterTools.java deleted file mode 100644 index 7a5d6ab89..000000000 --- a/MyBox/src/main/java/mara/mybox/image/ImageFilterTools.java +++ /dev/null @@ -1,245 +0,0 @@ -package mara.mybox.image; - -import java.awt.Color; -import java.awt.image.BufferedImage; -import static mara.mybox.objects.AppVaribles.logger; - - -/** - * @Author Mara - * @CreateDate 2018-11-10 20:08:19 - * @Version 1.0 - * @Description - * @License Apache License Version 2.0 - */ -public class ImageFilterTools { - - - - public static BufferedImage makeInvert(BufferedImage source) { - try { - int width = source.getWidth(); - int height = source.getHeight(); - int imageType = source.getType(); - if (imageType == BufferedImage.TYPE_CUSTOM) { - imageType = BufferedImage.TYPE_INT_ARGB; - } - BufferedImage target = new BufferedImage(width, height, imageType); - for (int j = 0; j < height; j++) { - for (int i = 0; i < width; i++) { - Color color = new Color(source.getRGB(i, j), true); - Color newColor = new Color(255 - color.getRed(), 255 - color.getGreen(), - 255 - color.getBlue(), color.getAlpha()); - target.setRGB(i, j, newColor.getRGB()); - } - } - return target; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - } - - public static BufferedImage makeRedInvert(BufferedImage source) { - try { - int width = source.getWidth(); - int height = source.getHeight(); - int imageType = source.getType(); - if (imageType == BufferedImage.TYPE_CUSTOM) { - imageType = BufferedImage.TYPE_INT_ARGB; - } - BufferedImage target = new BufferedImage(width, height, imageType); - for (int j = 0; j < height; j++) { - for (int i = 0; i < width; i++) { - Color color = new Color(source.getRGB(i, j), true); - Color newColor = new Color(255 - color.getRed(), color.getGreen(), - color.getBlue(), color.getAlpha()); - target.setRGB(i, j, newColor.getRGB()); - } - } - return target; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - } - - public static BufferedImage makeGreenInvert(BufferedImage source) { - try { - int width = source.getWidth(); - int height = source.getHeight(); - int imageType = source.getType(); - if (imageType == BufferedImage.TYPE_CUSTOM) { - imageType = BufferedImage.TYPE_INT_ARGB; - } - BufferedImage target = new BufferedImage(width, height, imageType); - for (int j = 0; j < height; j++) { - for (int i = 0; i < width; i++) { - Color color = new Color(source.getRGB(i, j), true); - Color newColor = new Color(color.getRed(), 255 - color.getGreen(), - color.getBlue(), color.getAlpha()); - target.setRGB(i, j, newColor.getRGB()); - } - } - return target; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - } - - public static BufferedImage makeBlueInvert(BufferedImage source) { - try { - int width = source.getWidth(); - int height = source.getHeight(); - int imageType = source.getType(); - if (imageType == BufferedImage.TYPE_CUSTOM) { - imageType = BufferedImage.TYPE_INT_ARGB; - } - BufferedImage target = new BufferedImage(width, height, imageType); - for (int j = 0; j < height; j++) { - for (int i = 0; i < width; i++) { - Color color = new Color(source.getRGB(i, j), true); - Color newColor = new Color(color.getRed(), color.getGreen(), - 255 - color.getBlue(), color.getAlpha()); - target.setRGB(i, j, newColor.getRGB()); - } - } - return target; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - } - - public static BufferedImage makeBinary(BufferedImage source, int percent) { - return ImageGrayTools.color2BinaryWithPercentage(source, percent); - } - - public static BufferedImage keepRed(BufferedImage source) { - try { - int width = source.getWidth(); - int height = source.getHeight(); - int imageType = source.getType(); - if (imageType == BufferedImage.TYPE_CUSTOM) { - imageType = BufferedImage.TYPE_INT_ARGB; - } - BufferedImage target = new BufferedImage(width, height, imageType); - for (int j = 0; j < height; j++) { - for (int i = 0; i < width; i++) { - target.setRGB(i, j, source.getRGB(i, j) & 0xFFFF0000); - } - } - return target; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - } - - public static BufferedImage keepGreen(BufferedImage source) { - try { - int width = source.getWidth(); - int height = source.getHeight(); - int imageType = source.getType(); - if (imageType == BufferedImage.TYPE_CUSTOM) { - imageType = BufferedImage.TYPE_INT_ARGB; - } - BufferedImage target = new BufferedImage(width, height, imageType); - for (int j = 0; j < height; j++) { - for (int i = 0; i < width; i++) { - target.setRGB(i, j, source.getRGB(i, j) & 0xFF00FF00); - } - } - return target; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - } - - public static BufferedImage keepBlue(BufferedImage source) { - try { - int width = source.getWidth(); - int height = source.getHeight(); - int imageType = source.getType(); - if (imageType == BufferedImage.TYPE_CUSTOM) { - imageType = BufferedImage.TYPE_INT_ARGB; - } - BufferedImage target = new BufferedImage(width, height, imageType); - for (int j = 0; j < height; j++) { - for (int i = 0; i < width; i++) { - target.setRGB(i, j, source.getRGB(i, j) & 0xFF0000FF); - } - } - return target; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - } - - public static BufferedImage keepYellow(BufferedImage source) { - try { - int width = source.getWidth(); - int height = source.getHeight(); - int imageType = source.getType(); - if (imageType == BufferedImage.TYPE_CUSTOM) { - imageType = BufferedImage.TYPE_INT_ARGB; - } - BufferedImage target = new BufferedImage(width, height, imageType); - for (int j = 0; j < height; j++) { - for (int i = 0; i < width; i++) { - target.setRGB(i, j, source.getRGB(i, j) & 0xFFFFFF00); - } - } - return target; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - } - - public static BufferedImage keepCyan(BufferedImage source) { - try { - int width = source.getWidth(); - int height = source.getHeight(); - int imageType = source.getType(); - if (imageType == BufferedImage.TYPE_CUSTOM) { - imageType = BufferedImage.TYPE_INT_ARGB; - } - BufferedImage target = new BufferedImage(width, height, imageType); - for (int j = 0; j < height; j++) { - for (int i = 0; i < width; i++) { - target.setRGB(i, j, source.getRGB(i, j) & 0xFF00FFFF); - } - } - return target; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - } - - public static BufferedImage keepMagenta(BufferedImage source) { - try { - int width = source.getWidth(); - int height = source.getHeight(); - int imageType = source.getType(); - if (imageType == BufferedImage.TYPE_CUSTOM) { - imageType = BufferedImage.TYPE_INT_ARGB; - } - BufferedImage target = new BufferedImage(width, height, imageType); - for (int j = 0; j < height; j++) { - for (int i = 0; i < width; i++) { - target.setRGB(i, j, source.getRGB(i, j) & 0xFFFF00FF); - } - } - return target; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - } - -} diff --git a/MyBox/src/main/java/mara/mybox/image/ImageGray.java b/MyBox/src/main/java/mara/mybox/image/ImageGray.java new file mode 100644 index 000000000..f52748333 --- /dev/null +++ b/MyBox/src/main/java/mara/mybox/image/ImageGray.java @@ -0,0 +1,83 @@ +package mara.mybox.image; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import javafx.embed.swing.SwingFXUtils; +import javafx.scene.image.Image; +import static mara.mybox.value.AppVaribles.logger; + +/** + * @Author Mara + * @CreateDate 2019-2-15 + * @Version 1.0 + * @Description + * @License Apache License Version 2.0 + */ +public class ImageGray extends PixelsOperation { + + public ImageGray() { + operationType = OperationType.Gray; + } + + @Override + public BufferedImage operate() { + if (image == null || operationType == null + || operationType != OperationType.Gray) { + return image; + } + + if (scope == null || scope.getScopeType() == ImageScope.ScopeType.All) { + return byteGray(image); + } + return operationImage(); + } + + @Override + protected Color operateColor(Color color) { + return ImageColor.RGB2Gray(color); + } + + public static BufferedImage byteGray(BufferedImage image) { + try { + int width = image.getWidth(); + int height = image.getHeight(); + BufferedImage grayImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY); + Graphics2D graphics = grayImage.createGraphics(); + graphics.drawImage(image, 0, 0, null); + return grayImage; + } catch (Exception e) { + logger.error(e.toString()); + return image; + } + } + + public static BufferedImage intGray(BufferedImage image) { + try { + int width = image.getWidth(); + int height = image.getHeight(); + BufferedImage grayImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + grayImage.setRGB(x, y, ImageColor.pixel2GrayPixel(image.getRGB(x, y))); + } + } + return grayImage; + } catch (Exception e) { + logger.error(e.toString()); + return image; + } + } + + public static Image gray(Image image) { + try { + BufferedImage bm = SwingFXUtils.fromFXImage(image, null); + bm = intGray(bm); + return SwingFXUtils.toFXImage(bm, null); + } catch (Exception e) { + logger.error(e.toString()); + return image; + } + } + +} diff --git a/MyBox/src/main/java/mara/mybox/image/ImageGrayTools.java b/MyBox/src/main/java/mara/mybox/image/ImageGrayTools.java deleted file mode 100644 index fad6702a3..000000000 --- a/MyBox/src/main/java/mara/mybox/image/ImageGrayTools.java +++ /dev/null @@ -1,257 +0,0 @@ -package mara.mybox.image; - -import mara.mybox.image.ImageColorTools; -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.color.ColorSpace; -import java.awt.image.BufferedImage; -import java.awt.image.ColorConvertOp; -import java.io.File; -import javax.imageio.ImageIO; - -import static mara.mybox.objects.AppVaribles.logger; - - -/** - * @Author Mara - * @CreateDate 2018-6-4 16:07:27 - * @Description - * @License Apache License Version 2.0 - */ -public class ImageGrayTools { - - - - public static BufferedImage color2Gray(BufferedImage source) { - try { - int width = source.getWidth(); - int height = source.getHeight(); - BufferedImage grayImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY); - Graphics2D graphics = grayImage.createGraphics(); - graphics.drawImage(source, 0, 0, null); - return grayImage; - } catch (Exception e) { - logger.error(e.toString()); - return source; - } - } - - public static BufferedImage color2Gray(BufferedImage source, boolean preserveChannels) { - try { - int width = source.getWidth(); - int height = source.getHeight(); - BufferedImage grayImage; - if (preserveChannels) { - grayImage = new BufferedImage(width, height, source.getType()); - } else { - grayImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY); - } - ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY); - ColorConvertOp theOp = new ColorConvertOp(cs, null); - theOp.filter(source, grayImage); - return grayImage; - } catch (Exception e) { - logger.error(e.toString()); - return source; - } - } - - public static int calculateThreshold(File file) { - try { - BufferedImage bufferImage = ImageIO.read(file); - return OTSU(color2Gray(bufferImage)); - } catch (Exception e) { - logger.error(e.toString()); - return -1; - } - - } - - // OTSU algorithm: ICV=PA∗(MA−M)2+PB∗(MB−M)2 - // https://blog.csdn.net/taoyanbian1022/article/details/9030825 - // https://blog.csdn.net/liyuanbhu/article/details/49387483 - public static int OTSU(BufferedImage grayImage) { - try { - int width = grayImage.getWidth(); - int height = grayImage.getHeight(); - - int[] grayNumber = new int[256]; - for (int i = 0; i < width; i++) { - for (int j = 0; j < height; j++) { -// int r = 0xFF & grayImage.getRGB(i, j); - int gray = ImageColorTools.grayPixel2GrayValue(grayImage.getRGB(i, j)); - grayNumber[gray]++; - } - } - - float pixelTotal = width * height; - float[] grayRadio = new float[256]; - for (int i = 0; i < 256; i++) { - grayRadio[i] = grayNumber[i] / pixelTotal; - } - - float backgroundNumber, foregroundNumber, backgoundValue, foregroundValue; - float backgoundAverage, foregroundAverage, imageAverage, delta, deltaMax = 0; - int threshold = 0; - for (int gray = 0; gray < 256; gray++) { - backgroundNumber = 0; - foregroundNumber = 0; - backgoundValue = 0; - foregroundValue = 0; - for (int i = 0; i < 256; i++) { - if (i <= gray) { - backgroundNumber += grayRadio[i]; - backgoundValue += i * grayRadio[i]; - } else { - foregroundNumber += grayRadio[i]; - foregroundValue += i * grayRadio[i]; - } - } - - backgoundAverage = backgoundValue / backgroundNumber; - foregroundAverage = foregroundValue / foregroundNumber; - imageAverage = backgoundValue + foregroundValue; - - delta = backgroundNumber * (backgoundAverage - imageAverage) * (backgoundAverage - imageAverage) - + foregroundNumber * (foregroundAverage - imageAverage) * (foregroundAverage - imageAverage); - - if (delta > deltaMax) { - deltaMax = delta; - threshold = gray; - } - } -// logger.debug("threshold:" + threshold); - return threshold; - - } catch (Exception e) { - logger.error(e.toString()); - return -1; - } - } - - public static int getIterationBinary(BufferedImage grayImage) { - try { - int width = grayImage.getWidth(); - int height = grayImage.getHeight(); - - int Threshold = 128; - int preThreshold = 256; - - while (Math.abs(Threshold - preThreshold) > 4) { - int s1 = 0; - int s2 = 0; - int f1 = 0; - int f2 = 0; - - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - int gray = grayImage.getRGB(x, y); - if (gray < Threshold) { - s1 += gray; - f1++; - } else { - s2 += gray; - f2++; - } - } - } - preThreshold = Threshold; - Threshold = (int) ((s1 / f1 + s2 / f2) / 2); - } - return Threshold; - } catch (Exception e) { - logger.error(e.toString()); - return -1; - } - } - - public static BufferedImage color2BinaryWithPercentage(BufferedImage image, int percentage) { - int threshold = 256 * percentage / 100; - return color2BinaryWithThreshold(image, threshold); - } - - public static BufferedImage color2BinaryWithThreshold(BufferedImage image, int threshold) { - try { - int width = image.getWidth(); - int height = image.getHeight(); - BufferedImage binaryImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY); - int white = Color.WHITE.getRGB(); - int black = Color.BLACK.getRGB(); - for (int i = 0; i < width; i++) { - for (int j = 0; j < height; j++) { - int pixel = image.getRGB(i, j); - int gray = ImageColorTools.pixel2GrayValue(pixel); - if (gray < threshold) { - binaryImage.setRGB(i, j, black); - } else { - binaryImage.setRGB(i, j, white); - } - } - } - return binaryImage; - } catch (Exception e) { - logger.error(e.toString()); - return image; - } - } - - public static BufferedImage color2BinaryByCalculation(BufferedImage image) { - try { - BufferedImage grayImage = color2Gray(image); - return gray2BinaryByCalculation(grayImage); - } catch (Exception e) { - logger.error(e.toString()); - return image; - } - } - - public static BufferedImage color2Binary(BufferedImage source) { - try { - int width = source.getWidth(); - int height = source.getHeight(); - BufferedImage binImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY); - Graphics2D graphics = binImage.createGraphics(); - graphics.drawImage(source, 0, 0, null); - return binImage; - } catch (Exception e) { - logger.error(e.toString()); - return source; - } - } - - public static BufferedImage gray2BinaryWithPercentage(BufferedImage grayImage, int percentage) { - int threshold = 256 * percentage / 100; - return gray2BinaryWithThreshold(grayImage, threshold); - } - - public static BufferedImage gray2BinaryWithThreshold(BufferedImage grayImage, int threshold) { - try { - int width = grayImage.getWidth(); - int height = grayImage.getHeight(); - BufferedImage binaryImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY); - int white = Color.WHITE.getRGB(); - int black = Color.BLACK.getRGB(); - for (int i = 0; i < width; i++) { - for (int j = 0; j < height; j++) { - int pixel = grayImage.getRGB(i, j); - int gray = ImageColorTools.grayPixel2GrayValue(pixel); - if (gray < threshold) { - binaryImage.setRGB(i, j, black); - } else { - binaryImage.setRGB(i, j, white); - } - } - } - return binaryImage; - } catch (Exception e) { - logger.error(e.toString()); - return grayImage; - } - } - - public static BufferedImage gray2BinaryByCalculation(BufferedImage grayImage) { - int threshold = OTSU(grayImage); - return gray2BinaryWithThreshold(grayImage, threshold); - } - -} diff --git a/MyBox/src/main/java/mara/mybox/image/ImageMarginsTools.java b/MyBox/src/main/java/mara/mybox/image/ImageMargins.java similarity index 96% rename from MyBox/src/main/java/mara/mybox/image/ImageMarginsTools.java rename to MyBox/src/main/java/mara/mybox/image/ImageMargins.java index 09206b996..093ac359f 100644 --- a/MyBox/src/main/java/mara/mybox/image/ImageMarginsTools.java +++ b/MyBox/src/main/java/mara/mybox/image/ImageMargins.java @@ -3,10 +3,10 @@ import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.BufferedImage; -import static mara.mybox.image.ImageConvertTools.cropImage; -import static mara.mybox.image.ImageConvertTools.hasAlpha; -import static mara.mybox.objects.CommonValues.AlphaColor; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.image.ImageConvert.cropImage; +import static mara.mybox.image.ImageConvert.hasAlpha; +import static mara.mybox.value.CommonValues.AlphaColor; +import static mara.mybox.value.AppVaribles.logger; /** @@ -16,7 +16,7 @@ * @Description * @License Apache License Version 2.0 */ -public class ImageMarginsTools { +public class ImageMargins { diff --git a/MyBox/src/main/java/mara/mybox/image/ImageQuantization.java b/MyBox/src/main/java/mara/mybox/image/ImageQuantization.java new file mode 100644 index 000000000..3b5827e02 --- /dev/null +++ b/MyBox/src/main/java/mara/mybox/image/ImageQuantization.java @@ -0,0 +1,217 @@ +package mara.mybox.image; + +import java.awt.Color; +import java.awt.image.BufferedImage; + +/** + * @Author Mara + * @CreateDate 2019-2-13 14:44:03 + * @Version 1.0 + * @Description + * @License Apache License Version 2.0 + */ +public class ImageQuantization extends PixelsOperation { + + protected QuantizationAlgorithm algorithm; + protected int channelSize, rgbMod, rgbOffset, + hueMod, saturationMod, brightnessMod, hueOffset, saturationOffset, brightnessOffset; + + public static enum QuantizationAlgorithm { + RGB_Uniform, HSB_Uniform, Statistic, MedianCut, kMeansClustering, ANN + } + + public ImageQuantization() { + init(QuantizationAlgorithm.RGB_Uniform, 8); + } + + public ImageQuantization(BufferedImage image) { + init(image, QuantizationAlgorithm.RGB_Uniform, 8); + } + + public ImageQuantization(BufferedImage image, QuantizationAlgorithm algorithm, int channelSize) { + init(image, algorithm, channelSize); + } + + private void init(QuantizationAlgorithm algorithm, int channelSize) { + set(algorithm, channelSize); + } + + private void init(BufferedImage image, QuantizationAlgorithm algorithm, int channelSize) { + this.image = image; + set(algorithm, channelSize); + } + + public void set(QuantizationAlgorithm algorithm, int channelSize) { + this.operationType = OperationType.Quantization; + this.algorithm = algorithm; + setChannelSize(channelSize); + } + + public void set(BufferedImage image, QuantizationAlgorithm algorithm, int channelSize, + int rgbMod, int rgbOffset, int hueMod, int saturationMod, int brightnessMod, + int hueOffset, int saturationOffset, int brightnessOffset) { + this.operationType = OperationType.Quantization; + this.image = image; + this.algorithm = algorithm; + this.channelSize = channelSize; + this.rgbMod = rgbMod; + this.rgbOffset = rgbOffset; + this.hueMod = hueMod; + this.hueOffset = hueOffset; + this.saturationMod = saturationMod; + this.saturationOffset = saturationOffset; + this.brightnessMod = brightnessMod; + this.brightnessOffset = brightnessOffset; + } + + public void setChannelSize(int channelSize) { + this.channelSize = channelSize; + rgbMod = 256 / channelSize; + rgbOffset = rgbMod / 2; + hueMod = 360 / channelSize; + hueOffset = hueMod / 2; + saturationMod = brightnessMod = 100 / channelSize; + saturationOffset = brightnessOffset = saturationMod / 2; + } + + @Override + public Color operateColor(Color color) { + switch (algorithm) { + case RGB_Uniform: + return rgbColorUniform(color); + case HSB_Uniform: + return hsbColorUniform(color); + case Statistic: + return rgbColorUniform(color); + case kMeansClustering: + return rgbColorUniform(color); + case ANN: + return rgbColorUniform(color); + default: + return rgbColorUniform(color); + } + + } + + public Color rgbColorUniform(Color color) { + if (rgbMod <= 0) { + return color; + } + int red, green, blue; + + int v = color.getRed(); + v = v - (v % rgbMod) + rgbOffset; + red = Math.min(Math.max(v, 0), 255); + + v = color.getGreen(); + v = v - (v % rgbMod) + rgbOffset; + green = Math.min(Math.max(v, 0), 255); + + v = color.getBlue(); + v = v - (v % rgbMod) + rgbOffset; + blue = Math.min(Math.max(v, 0), 255); + + Color newColor = new Color(red, green, blue, color.getAlpha()); + return newColor; + } + + public Color hsbColorUniform(Color color) { + if (hueMod <= 0 || saturationMod <= 0 || brightnessMod <= 0) { + return color; + } + float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null); + float h, s, b; + + int v = (int) (hsb[0] * 360); + v = v - (v % hueMod) + hueOffset; + h = (float) Math.min(Math.max(v / 360.0f, 0.0f), 1.0f); + + v = (int) (hsb[1] * 100); + v = v - (v % saturationMod) + saturationOffset; + s = (float) Math.min(Math.max(v / 100.0f, 0.0f), 1.0f); + + v = (int) (hsb[2] * 100); + v = v - (v % brightnessMod) + brightnessOffset; + b = (float) Math.min(Math.max(v / 100.0f, 0.0f), 1.0f); + + Color newColor = Color.getHSBColor(h, s, b); + return newColor; + } + + public QuantizationAlgorithm getAlgorithm() { + return algorithm; + } + + public void setAlgorithm(QuantizationAlgorithm algorithm) { + this.algorithm = algorithm; + } + + public int getChannelSize() { + return channelSize; + } + + public int getRgbMod() { + return rgbMod; + } + + public void setRgbMod(int rgbMod) { + this.rgbMod = rgbMod; + } + + public int getRgbOffset() { + return rgbOffset; + } + + public void setRgbOffset(int rgbOffset) { + this.rgbOffset = rgbOffset; + } + + public int getHueMod() { + return hueMod; + } + + public void setHueMod(int hueMod) { + this.hueMod = hueMod; + } + + public int getSaturationMod() { + return saturationMod; + } + + public void setSaturationMod(int saturationMod) { + this.saturationMod = saturationMod; + } + + public int getBrightnessMod() { + return brightnessMod; + } + + public void setBrightnessMod(int brightnessMod) { + this.brightnessMod = brightnessMod; + } + + public int getHueOffset() { + return hueOffset; + } + + public void setHueOffset(int hueOffset) { + this.hueOffset = hueOffset; + } + + public int getSaturationOffset() { + return saturationOffset; + } + + public void setSaturationOffset(int saturationOffset) { + this.saturationOffset = saturationOffset; + } + + public int getBrightnessOffset() { + return brightnessOffset; + } + + public void setBrightnessOffset(int brightnessOffset) { + this.brightnessOffset = brightnessOffset; + } + +} diff --git a/MyBox/src/main/java/mara/mybox/image/ImageReplaceColorTools.java b/MyBox/src/main/java/mara/mybox/image/ImageReplaceColorTools.java deleted file mode 100644 index 9b58a43ba..000000000 --- a/MyBox/src/main/java/mara/mybox/image/ImageReplaceColorTools.java +++ /dev/null @@ -1,124 +0,0 @@ -package mara.mybox.image; - -import java.awt.Color; -import java.awt.image.BufferedImage; -import static mara.mybox.objects.CommonValues.AlphaColor; -import static mara.mybox.objects.AppVaribles.logger; - - -/** - * @Author Mara - * @CreateDate 2018-11-10 20:15:43 - * @Version 1.0 - * @Description - * @License Apache License Version 2.0 - */ -public class ImageReplaceColorTools { - - - - public static BufferedImage replaceColor(BufferedImage source, - Color oldColor, Color newColor, int distance, - boolean isColor, boolean excluded) { - try { - int width = source.getWidth(); - int height = source.getHeight(); - int newValue = newColor.getRGB(); - int imageType = source.getType(); - if (newColor.getRGB() == AlphaColor.getRGB()) { - imageType = BufferedImage.TYPE_INT_ARGB; - } - BufferedImage target = new BufferedImage(width, height, imageType); - for (int j = 0; j < height; j++) { - for (int i = 0; i < width; i++) { - int color = source.getRGB(i, j); - if (ImageColorTools.matchColor(new Color(color), oldColor, distance, isColor, excluded)) { - target.setRGB(i, j, newValue); - } else { - target.setRGB(i, j, color); - } - } - } - return target; - } catch (Exception e) { - logger.error(e.toString()); - return null; - } - } - -// public static Image replaceColorsRectangle(Image image, Color newColor, int x1, int y1, int x2, int y2) { -// PixelReader pixelReader = image.getPixelReader(); -// WritableImage newImage = new WritableImage((int) image.getWidth(), (int) image.getHeight()); -// PixelWriter pixelWriter = newImage.getPixelWriter(); -// -// for (int y = 0; y < image.getHeight(); y++) { -// for (int x = 0; x < image.getWidth(); x++) { -// if (x >= x1 && x <= x2 && y >= y1 && y <= y2) { -// pixelWriter.setColor(x, y, newColor); -// } else { -// pixelWriter.setColor(x, y, pixelReader.getColor(x, y)); -// } -// } -// } -// return newImage; -// } -// -// public static Image replaceColorsCircle(Image image, Color newColor, int cx, int cy, int r) { -// PixelReader pixelReader = image.getPixelReader(); -// WritableImage newImage = new WritableImage((int) image.getWidth(), (int) image.getHeight()); -// PixelWriter pixelWriter = newImage.getPixelWriter(); -// -// int r2 = r * r; -// for (int y = 0; y < image.getHeight(); y++) { -// for (int x = 0; x < image.getWidth(); x++) { -// Color color = pixelReader.getColor(x, y); -// int distanceX = cx - x; -// int distaneY = cy - y; -// if (distanceX * distanceX + distaneY * distaneY <= r2) { -// pixelWriter.setColor(x, y, newColor); -// } else { -// pixelWriter.setColor(x, y, color); -// } -// } -// } -// return newImage; -// } -// -// public static Image replaceColorsMatting(Image source, Color newColor, -// int startx, int starty, int distance) { -// try { -// int width = (int) source.getWidth(); -// int height = (int) source.getHeight(); -// PixelReader pixelReader = source.getPixelReader(); -// WritableImage newImage = new WritableImage(width, height); -// PixelWriter pixelWriter = newImage.getPixelWriter(); -// pixelWriter.setPixels(0, 0, width, height, pixelReader, 0, 0); -// -// Color startColor = pixelReader.getColor(startx, starty); -// boolean[][] visited = new boolean[height][width]; -// Queue queue = new LinkedList<>(); -// queue.add(new Point(startx, starty)); -// -// while (!queue.isEmpty()) { -// Point p = queue.remove(); -// if (p.x < 0 || p.x >= width || p.y < 0 || p.y >= height || visited[p.y][p.x]) { -// continue; -// } -// visited[p.y][p.x] = true; -// Color pixelColor = pixelReader.getColor(p.x, p.y); -// if (isColorMatch(pixelColor, startColor, distance)) { -// pixelWriter.setColor(p.x, p.y, newColor); -// queue.add(new Point(p.x + 1, p.y)); -// queue.add(new Point(p.x - 1, p.y)); -// queue.add(new Point(p.x, p.y + 1)); -// queue.add(new Point(p.x, p.y - 1)); -// } -// } -// return newImage; -// } catch (Exception e) { -// logger.error(e.toString()); -// return null; -// } -// -// } -} diff --git a/MyBox/src/main/java/mara/mybox/objects/ImageScope.java b/MyBox/src/main/java/mara/mybox/image/ImageScope.java similarity index 68% rename from MyBox/src/main/java/mara/mybox/objects/ImageScope.java rename to MyBox/src/main/java/mara/mybox/image/ImageScope.java index b6b0bf376..d479ef81e 100644 --- a/MyBox/src/main/java/mara/mybox/objects/ImageScope.java +++ b/MyBox/src/main/java/mara/mybox/image/ImageScope.java @@ -1,13 +1,13 @@ -package mara.mybox.objects; +package mara.mybox.image; +import java.awt.Color; import java.util.ArrayList; import java.util.List; import javafx.scene.image.Image; -import javafx.scene.paint.Color; -import mara.mybox.fxml.FxmlColorTools; -import static mara.mybox.objects.AppVaribles.getMessage; -import static mara.mybox.objects.AppVaribles.logger; - +import mara.mybox.data.IntCircle; +import mara.mybox.data.IntPoint; +import mara.mybox.data.IntRectangle; +import static mara.mybox.value.AppVaribles.getMessage; /** * @Author Mara @@ -17,25 +17,18 @@ */ public class ImageScope { - - - private OperationType operationType; private ScopeType scopeType; private ColorScopeType colorScopeType; private List colors; private List points; private IntRectangle rectangle; private IntCircle circle; - private double colorDistance; - private int hueDistance; + private int colorDistance, colorDistance2; + private float hsbDistance; private boolean areaExcluded, colorExcluded; private Image image; private double opacity; - public enum OperationType { - Invalid, Color, Effects, ReplaceColor, Convolution - } - public enum ScopeType { Invalid, All, Matting, Rectangle, Circle, Color, RectangleColor, CircleColor } @@ -45,31 +38,25 @@ public enum ColorScopeType { } public ImageScope() { - operationType = OperationType.Invalid; - scopeType = ScopeType.All; - colorScopeType = ColorScopeType.AllColor; - colors = new ArrayList(); - points = new ArrayList(); - colorDistance = 50 / 255.0; - hueDistance = 10; - opacity = 0.3; - areaExcluded = colorExcluded = false; - rectangle = new IntRectangle(); - circle = new IntCircle(); + init(); } public ImageScope(Image image) { - operationType = OperationType.Invalid; + this.image = image; + init(); + } + + private void init() { scopeType = ScopeType.All; colorScopeType = ColorScopeType.AllColor; colors = new ArrayList(); points = new ArrayList(); - colorDistance = 50 / 255.0; - hueDistance = 10; + colorDistance = 50; + colorDistance2 = colorDistance * colorDistance; + hsbDistance = 0.5f; opacity = 0.3; - areaExcluded = colorExcluded = false; + circle = new IntCircle(); if (image != null) { - this.image = image; rectangle = new IntRectangle((int) (image.getWidth() / 4), (int) (image.getHeight() / 4), (int) (image.getWidth() * 3 / 4), (int) (image.getHeight() * 3 / 4)); circle = new IntCircle((int) (image.getWidth() / 2), (int) (image.getHeight() / 2), @@ -78,11 +65,11 @@ public ImageScope(Image image) { rectangle = new IntRectangle(); circle = new IntCircle(); } + } public ImageScope cloneValues() { ImageScope scope = new ImageScope(image); - scope.setOperationType(operationType); scope.setScopeType(scopeType); scope.setColorScopeType(colorScopeType); List npoints = new ArrayList<>(); @@ -98,7 +85,8 @@ public ImageScope cloneValues() { scope.setRectangle(rectangle.cloneValues()); scope.setCircle(circle.cloneValues()); scope.setColorDistance(colorDistance); - scope.setHueDistance(hueDistance); + scope.setColorDistance2(colorDistance2); + scope.setHsbDistance(hsbDistance); scope.setColorExcluded(colorExcluded); scope.setAreaExcluded(areaExcluded); scope.setOpacity(opacity); @@ -159,14 +147,14 @@ public boolean inColorScope(Color color) { case Color: if (colorExcluded) { for (Color oColor : colors) { - if (FxmlColorTools.isColorMatch(color, oColor, colorDistance)) { + if (ImageColor.isColorMatch2(color, oColor, colorDistance2)) { return false; } } return true; } else { for (Color oColor : colors) { - if (FxmlColorTools.isColorMatch(color, oColor, colorDistance)) { + if (ImageColor.isColorMatch2(color, oColor, colorDistance2)) { return true; } } @@ -175,14 +163,14 @@ public boolean inColorScope(Color color) { case Red: if (colorExcluded) { for (Color oColor : colors) { - if (FxmlColorTools.isRedMatch(color, oColor, colorDistance)) { + if (ImageColor.isRedMatch(color, oColor, colorDistance)) { return false; } } return true; } else { for (Color oColor : colors) { - if (FxmlColorTools.isRedMatch(color, oColor, colorDistance)) { + if (ImageColor.isRedMatch(color, oColor, colorDistance)) { return true; } } @@ -191,14 +179,14 @@ public boolean inColorScope(Color color) { case Green: if (colorExcluded) { for (Color oColor : colors) { - if (FxmlColorTools.isGreenMatch(color, oColor, colorDistance)) { + if (ImageColor.isGreenMatch(color, oColor, colorDistance)) { return false; } } return true; } else { for (Color oColor : colors) { - if (FxmlColorTools.isGreenMatch(color, oColor, colorDistance)) { + if (ImageColor.isGreenMatch(color, oColor, colorDistance)) { return true; } } @@ -207,14 +195,14 @@ public boolean inColorScope(Color color) { case Blue: if (colorExcluded) { for (Color oColor : colors) { - if (FxmlColorTools.isBlueMatch(color, oColor, colorDistance)) { + if (ImageColor.isBlueMatch(color, oColor, colorDistance)) { return false; } } return true; } else { for (Color oColor : colors) { - if (FxmlColorTools.isBlueMatch(color, oColor, colorDistance)) { + if (ImageColor.isBlueMatch(color, oColor, colorDistance)) { return true; } } @@ -223,14 +211,14 @@ public boolean inColorScope(Color color) { case Brightness: if (colorExcluded) { for (Color oColor : colors) { - if (FxmlColorTools.isBrightnessMatch(color, oColor, colorDistance)) { + if (ImageColor.isBrightnessMatch(color, oColor, hsbDistance)) { return false; } } return true; } else { for (Color oColor : colors) { - if (FxmlColorTools.isBrightnessMatch(color, oColor, colorDistance)) { + if (ImageColor.isBrightnessMatch(color, oColor, hsbDistance)) { return true; } } @@ -239,14 +227,14 @@ public boolean inColorScope(Color color) { case Saturation: if (colorExcluded) { for (Color oColor : colors) { - if (FxmlColorTools.isSaturationMatch(color, oColor, colorDistance)) { + if (ImageColor.isSaturationMatch(color, oColor, hsbDistance)) { return false; } } return true; } else { for (Color oColor : colors) { - if (FxmlColorTools.isSaturationMatch(color, oColor, colorDistance)) { + if (ImageColor.isSaturationMatch(color, oColor, hsbDistance)) { return true; } } @@ -255,14 +243,14 @@ public boolean inColorScope(Color color) { case Hue: if (colorExcluded) { for (Color oColor : colors) { - if (FxmlColorTools.isHueMatch(color, oColor, hueDistance)) { + if (ImageColor.isHueMatch(color, oColor, hsbDistance)) { return false; } } return true; } else { for (Color oColor : colors) { - if (FxmlColorTools.isHueMatch(color, oColor, hueDistance)) { + if (ImageColor.isHueMatch(color, oColor, hsbDistance)) { return true; } } @@ -273,6 +261,90 @@ public boolean inColorScope(Color color) { } } + public boolean inColorMatch2(Color color1, Color color2) { + switch (colorScopeType) { + case AllColor: + return true; + case Color: + if (colorExcluded) { + return !ImageColor.isColorMatch2(color1, color2, colorDistance2); + } else { + return ImageColor.isColorMatch2(color1, color2, colorDistance2); + } + case Red: + if (colorExcluded) { + return !ImageColor.isRedMatch(color1, color2, colorDistance); + } else { + return ImageColor.isRedMatch(color1, color2, colorDistance); + } + case Green: + if (colorExcluded) { + return !ImageColor.isGreenMatch(color1, color2, colorDistance); + } else { + return ImageColor.isGreenMatch(color1, color2, colorDistance); + } + case Blue: + if (colorExcluded) { + return !ImageColor.isBlueMatch(color1, color2, colorDistance); + } else { + return ImageColor.isBlueMatch(color1, color2, colorDistance); + } + case Brightness: + if (colorExcluded) { + return !ImageColor.isBrightnessMatch(color1, color2, hsbDistance); + } else { + return ImageColor.isBrightnessMatch(color1, color2, hsbDistance); + } + case Saturation: + if (colorExcluded) { + return !ImageColor.isSaturationMatch(color1, color2, hsbDistance); + } else { + return ImageColor.isSaturationMatch(color1, color2, hsbDistance); + } + case Hue: + if (colorExcluded) { + return !ImageColor.isHueMatch(color1, color2, hsbDistance); + } else { + return ImageColor.isHueMatch(color1, color2, hsbDistance); + } + default: + return false; + } + } + + public boolean inColorMatch(Color color1, Color color2) { + boolean isMatch; + switch (colorScopeType) { + case AllColor: + isMatch = true; + break; + case Color: + isMatch = ImageColor.isColorMatch2(color1, color2, colorDistance2); + break; + case Red: + isMatch = ImageColor.isRedMatch(color1, color2, colorDistance); + break; + case Green: + isMatch = ImageColor.isGreenMatch(color1, color2, colorDistance); + break; + case Blue: + isMatch = ImageColor.isBlueMatch(color1, color2, colorDistance); + break; + case Brightness: + isMatch = ImageColor.isBrightnessMatch(color1, color2, hsbDistance); + break; + case Saturation: + isMatch = ImageColor.isSaturationMatch(color1, color2, hsbDistance); + break; + case Hue: + isMatch = ImageColor.isHueMatch(color1, color2, hsbDistance); + break; + default: + isMatch = false; + } + return isMatch; + } + public void addPoints(IntPoint point) { if (point == null) { return; @@ -345,7 +417,7 @@ public String getScopeText() { } } s = getMessage("Points") + ":" + pointsString; - s += " " + getMessage("ColorDistance") + ":" + (int) (colorDistance * 255); + s += " " + getMessage("ColorDistance") + ":" + colorDistance; break; case Color: s = getScopeColorText(); @@ -376,7 +448,7 @@ public String getScopeColorText() { case Green: case Blue: s += " " + getMessage("SelectedColors") + ":" + colorString; - s += getMessage("ColorDistance") + ":" + (int) (colorDistance * 255); + s += getMessage("ColorDistance") + ":" + colorDistance; if (colorExcluded) { s += " " + getMessage("Excluded"); } @@ -384,14 +456,14 @@ public String getScopeColorText() { case Brightness: case Saturation: s += " " + getMessage("SelectedColors") + ":" + colorString; - s += getMessage("ColorDistance") + ":" + (int) (colorDistance * 100); + s += getMessage("ColorDistance") + ":" + (int) (hsbDistance * 100); if (colorExcluded) { s += " " + getMessage("Excluded"); } break; case Hue: s += " " + getMessage("SelectedColors") + ":" + colorString; - s += getMessage("HueDistance") + ":" + hueDistance; + s += getMessage("HueDistance") + ":" + (int) (hsbDistance * 360); if (colorExcluded) { s += " " + getMessage("Excluded"); } @@ -434,20 +506,13 @@ public void setImage(Image image) { this.image = image; } - public double getColorDistance() { + public int getColorDistance() { return colorDistance; } - public void setColorDistance(double colorDistance) { + public void setColorDistance(int colorDistance) { this.colorDistance = colorDistance; - } - - public int getHueDistance() { - return hueDistance; - } - - public void setHueDistance(int hueDistance) { - this.hueDistance = hueDistance; + this.colorDistance2 = colorDistance * colorDistance; } public double getOpacity() { @@ -458,14 +523,6 @@ public void setOpacity(double opacity) { this.opacity = opacity; } - public OperationType getOperationType() { - return operationType; - } - - public void setOperationType(OperationType operationType) { - this.operationType = operationType; - } - public ScopeType getScopeType() { return scopeType; } @@ -506,4 +563,20 @@ public void setPoints(List points) { this.points = points; } + public int getColorDistance2() { + return colorDistance2; + } + + public void setColorDistance2(int colorDistance2) { + this.colorDistance2 = colorDistance2; + } + + public float getHsbDistance() { + return hsbDistance; + } + + public void setHsbDistance(float hsbDistance) { + this.hsbDistance = hsbDistance; + } + } diff --git a/MyBox/src/main/java/mara/mybox/image/ImageScopeTools.java b/MyBox/src/main/java/mara/mybox/image/ImageScopeTools.java index 7c3c7ff9d..bddf235df 100644 --- a/MyBox/src/main/java/mara/mybox/image/ImageScopeTools.java +++ b/MyBox/src/main/java/mara/mybox/image/ImageScopeTools.java @@ -8,9 +8,9 @@ import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.List; -import mara.mybox.objects.IntCircle; -import mara.mybox.objects.IntRectangle; -import static mara.mybox.objects.AppVaribles.logger; +import mara.mybox.data.IntCircle; +import mara.mybox.data.IntRectangle; +import static mara.mybox.value.AppVaribles.logger; /** diff --git a/MyBox/src/main/java/mara/mybox/image/ImageStatistic.java b/MyBox/src/main/java/mara/mybox/image/ImageStatistic.java new file mode 100644 index 000000000..718301083 --- /dev/null +++ b/MyBox/src/main/java/mara/mybox/image/ImageStatistic.java @@ -0,0 +1,271 @@ +package mara.mybox.image; + +import java.awt.Color; +import java.awt.image.BufferedImage; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import mara.mybox.data.IntStatistic; +import static mara.mybox.value.AppVaribles.logger; + +/** + * @Author Mara + * @CreateDate 2019-2-8 19:26:01 + * @Version 1.0 + * @Description + * @License Apache License Version 2.0 + */ +public class ImageStatistic { + + private BufferedImage image; + + public ImageStatistic() { + } + + public ImageStatistic(BufferedImage image) { + this.image = image; + } + + public int[] grayHistogram() { + return grayHistogram(image); + } + + public static int[] grayHistogram(BufferedImage image) { + if (image == null) { + return null; + } + BufferedImage grayImage = ImageGray.byteGray(image); + int[] histogram = new int[256]; + for (int y = 0; y < image.getHeight(); y++) { + for (int x = 0; x < image.getWidth(); x++) { + int grey = new Color(grayImage.getRGB(x, y)).getRed(); + histogram[grey]++; + } + } + return histogram; + } + + public static Map analyze(BufferedImage image) { + Map data = new HashMap<>(); + try { + if (image == null) { + return data; + } + int[] greyHistogram = new int[256]; + int[] redHistogram = new int[256]; + int[] greenHistogram = new int[256]; + int[] blueHistogram = new int[256]; + int[] alphaHistogram = new int[256]; + int[] hueHistogram = new int[361]; + int[] saturationHistogram = new int[101]; + int[] brightnessHistogram = new int[101]; + Color color; + long redSum, greenSum, blueSum, alphaSum, hueSum, saturationSum, brightnessSum, greySum; + redSum = greenSum = blueSum = alphaSum = hueSum = saturationSum = brightnessSum = greySum = 0; + int redMaximum, greenMaximum, blueMaximum, alphaMaximum, hueMaximum, saturationMaximum, brightnessMaximum, greyMaximum; + redMaximum = greenMaximum = blueMaximum = alphaMaximum = hueMaximum = saturationMaximum = brightnessMaximum = greyMaximum = 0; + int redMinimum, greenMinimum, blueMinimum, alphaMinimum, hueMinimum, saturationMinimum, brightnessMinimum, greyMinimum; + redMinimum = greenMinimum = blueMinimum = alphaMinimum = hueMinimum = saturationMinimum = brightnessMinimum = greyMinimum = 255; + int v; + for (int y = 0; y < image.getHeight(); y++) { + for (int x = 0; x < image.getWidth(); x++) { + color = new Color(image.getRGB(x, y)); + + v = color.getRed(); + redHistogram[v]++; + redSum += v; + if (v > redMaximum) { + redMaximum = v; + } + if (v < redMinimum) { + redMinimum = v; + } + + v = color.getGreen(); + greenHistogram[v]++; + greenSum += v; + if (v > greenMaximum) { + greenMaximum = v; + } + if (v < greenMinimum) { + greenMinimum = v; + } + + v = color.getBlue(); + blueHistogram[v]++; + blueSum += v; + if (v > blueMaximum) { + blueMaximum = v; + } + if (v < blueMinimum) { + blueMinimum = v; + } + + v = color.getAlpha(); + alphaHistogram[v]++; + alphaSum += v; + if (v > alphaMaximum) { + alphaMaximum = v; + } + if (v < alphaMinimum) { + alphaMinimum = v; + } + + v = (int) (ImageColor.getHue(color) * 360); + hueHistogram[v]++; + hueSum += v; + if (v > hueMaximum) { + hueMaximum = v; + } + if (v < hueMinimum) { + hueMinimum = v; + } + + v = (int) (ImageColor.getSaturation(color) * 100); + saturationHistogram[v]++; + saturationSum += v; + if (v > saturationMaximum) { + saturationMaximum = v; + } + if (v < saturationMinimum) { + saturationMinimum = v; + } + + v = (int) (ImageColor.getBrightness(color) * 100); + brightnessHistogram[v]++; + brightnessSum += v; + if (v > brightnessMaximum) { + brightnessMaximum = v; + } + if (v < brightnessMinimum) { + brightnessMinimum = v; + } + + v = ImageColor.RGB2GrayValue(color); + greyHistogram[v]++; + greySum += v; + if (v > greyMaximum) { + greyMaximum = v; + } + if (v < greyMinimum) { + greyMinimum = v; + } + + } + } + data.put("greyHistogram", greyHistogram); + data.put("redHistogram", redHistogram); + data.put("greenHistogram", greenHistogram); + data.put("blueHistogram", blueHistogram); + data.put("alphaHistogram", alphaHistogram); + data.put("hueHistogram", hueHistogram); + data.put("saturationHistogram", saturationHistogram); + data.put("brightnessHistogram", brightnessHistogram); + + long pxielsNumber = image.getWidth() * image.getHeight(); + int redMean = (int) (redSum / pxielsNumber); + int greenMean = (int) (greenSum / pxielsNumber); + int blueMean = (int) (blueSum / pxielsNumber); + int alphaMean = (int) (alphaSum / pxielsNumber); + int hueMean = (int) (hueSum / pxielsNumber); + int saturationMean = (int) (saturationSum / pxielsNumber); + int brightnessMean = (int) (brightnessSum / pxielsNumber); + int greyMean = (int) (greySum / pxielsNumber); + + long redVariable, greenVariable, blueVariable, alphaVariable, hueVariable, saturationVariable, brightnessVariable, greyVariable; + redVariable = greenVariable = blueVariable = alphaVariable = hueVariable = saturationVariable = brightnessVariable = greyVariable = 0; + long redSkewness, greenSkewness, blueSkewness, alphaSkewness, hueSkewness, saturationSkewness, brightnessSkewness, greySkewness; + redSkewness = greenSkewness = blueSkewness = alphaSkewness = hueSkewness = saturationSkewness = brightnessSkewness = greySkewness = 0; + for (int y = 0; y < image.getHeight(); y++) { + for (int x = 0; x < image.getWidth(); x++) { + color = new Color(image.getRGB(x, y)); + + v = color.getRed(); + redVariable += Math.pow(v - redMean, 2); + redSkewness += Math.pow(v - redMean, 3); + + v = color.getGreen(); + greenVariable += Math.pow(v - greenMean, 2); + greenSkewness += Math.pow(v - greenMean, 3); + + v = color.getBlue(); + blueVariable += Math.pow(v - blueMean, 2); + blueSkewness += Math.pow(v - blueMean, 3); + + v = color.getAlpha(); + alphaVariable += Math.pow(v - alphaMean, 2); + alphaSkewness += Math.pow(v - alphaMean, 3); + + v = (int) (ImageColor.getHue(color) * 100); + hueVariable += Math.pow(v - hueMean, 2); + hueSkewness += Math.pow(v - hueMean, 3); + + v = (int) (ImageColor.getSaturation(color) * 100); + saturationVariable += Math.pow(v - saturationMean, 2); + saturationSkewness += Math.pow(v - saturationMean, 3); + + v = (int) (ImageColor.getBrightness(color) * 100); + brightnessVariable += Math.pow(v - brightnessMean, 2); + brightnessSkewness += Math.pow(v - brightnessMean, 3); + + v = ImageColor.RGB2GrayValue(color); + greyVariable += Math.pow(v - greyMean, 2); + greySkewness += Math.pow(v - greyMean, 3); + + } + } + + redVariable = (int) Math.sqrt(redVariable / pxielsNumber); + greenVariable = (int) Math.sqrt(greenVariable / pxielsNumber); + blueVariable = (int) Math.sqrt(blueVariable / pxielsNumber); + alphaVariable = (int) Math.sqrt(alphaVariable / pxielsNumber); + hueVariable = (int) Math.sqrt(hueVariable / pxielsNumber); + saturationVariable = (int) Math.sqrt(saturationVariable / pxielsNumber); + brightnessVariable = (int) Math.sqrt(brightnessVariable / pxielsNumber); + greyVariable = (int) Math.sqrt(greyVariable / pxielsNumber); + + redSkewness = (int) Math.pow(redSkewness / pxielsNumber, 1.0 / 3); + greenSkewness = (int) Math.pow(greenSkewness / pxielsNumber, 1.0 / 3); + blueSkewness = (int) Math.pow(blueSkewness / pxielsNumber, 1.0 / 3); + alphaSkewness = (int) Math.pow(alphaSkewness / pxielsNumber, 1.0 / 3); + hueSkewness = (int) Math.pow(hueSkewness / pxielsNumber, 1.0 / 3); + saturationSkewness = (int) Math.pow(saturationSkewness / pxielsNumber, 1.0 / 3); + brightnessSkewness = (int) Math.pow(brightnessSkewness / pxielsNumber, 1.0 / 3); + greySkewness = (int) Math.pow(greySkewness / pxielsNumber, 1.0 / 3); + + List statistic = new ArrayList<>(); + statistic.add(new IntStatistic("Grey", greySum, greyMean, (int) greyVariable, (int) greySkewness, + greyMinimum, greyMaximum, IntStatistic.maximumIndex(greyHistogram))); + statistic.add(new IntStatistic("Red", redSum, redMean, (int) redVariable, (int) redSkewness, + redMinimum, redMaximum, IntStatistic.maximumIndex(redHistogram))); + statistic.add(new IntStatistic("Green", greenSum, greenMean, (int) greenVariable, (int) greenSkewness, + greenMinimum, greenMaximum, IntStatistic.maximumIndex(greenHistogram))); + statistic.add(new IntStatistic("Blue", blueSum, blueMean, (int) blueVariable, (int) blueSkewness, + blueMinimum, blueMaximum, IntStatistic.maximumIndex(blueHistogram))); + statistic.add(new IntStatistic("Alpha", alphaSum, alphaMean, (int) alphaVariable, (int) alphaSkewness, + alphaMinimum, alphaMaximum, IntStatistic.maximumIndex(alphaHistogram))); + statistic.add(new IntStatistic("Hue", hueSum, hueMean, (int) hueVariable, (int) hueSkewness, + hueMinimum, hueMaximum, IntStatistic.maximumIndex(hueHistogram))); + statistic.add(new IntStatistic("Saturation", saturationSum, saturationMean, (int) saturationVariable, (int) saturationSkewness, + saturationMinimum, saturationMaximum, IntStatistic.maximumIndex(saturationHistogram))); + statistic.add(new IntStatistic("Brightness", brightnessSum, brightnessMean, (int) brightnessVariable, (int) brightnessSkewness, + brightnessMinimum, brightnessMaximum, IntStatistic.maximumIndex(brightnessHistogram))); + + data.put("statistic", statistic); + + } catch (Exception e) { + logger.debug(e.toString()); + } + return data; + } + + public BufferedImage getImage() { + return image; + } + + public void setImage(BufferedImage image) { + this.image = image; + } + +} diff --git a/MyBox/src/main/java/mara/mybox/image/ImageTransformTools.java b/MyBox/src/main/java/mara/mybox/image/ImageTransform.java similarity index 94% rename from MyBox/src/main/java/mara/mybox/image/ImageTransformTools.java rename to MyBox/src/main/java/mara/mybox/image/ImageTransform.java index 33a4fc40e..38778d790 100644 --- a/MyBox/src/main/java/mara/mybox/image/ImageTransformTools.java +++ b/MyBox/src/main/java/mara/mybox/image/ImageTransform.java @@ -4,8 +4,8 @@ import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.image.BufferedImage; -import static mara.mybox.objects.CommonValues.AlphaColor; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.CommonValues.AlphaColor; +import static mara.mybox.value.AppVaribles.logger; /** @@ -15,7 +15,7 @@ * @Description * @License Apache License Version 2.0 */ -public class ImageTransformTools { +public class ImageTransform { @@ -72,7 +72,7 @@ public static BufferedImage rotateImage(BufferedImage source, int angle) { g.dispose(); // logger.debug("Rotated: " + newWidth + ", " + newHeight); - target = ImageMarginsTools.cutMargins(target, bgColor, true, true, true, true); + target = ImageMargins.cutMargins(target, bgColor, true, true, true, true); return target; } @@ -154,7 +154,7 @@ public static BufferedImage shearImage(BufferedImage source, float shearX, float g.drawImage(source, 0, 0, null); g.dispose(); - target = ImageMarginsTools.cutMargins(target, bgColor, true, true, true, true); + target = ImageMargins.cutMargins(target, bgColor, true, true, true, true); return target; } catch (Exception e) { logger.error(e.toString()); diff --git a/MyBox/src/main/java/mara/mybox/image/ImageValueTools.java b/MyBox/src/main/java/mara/mybox/image/ImageValue.java similarity index 98% rename from MyBox/src/main/java/mara/mybox/image/ImageValueTools.java rename to MyBox/src/main/java/mara/mybox/image/ImageValue.java index 00e870820..ae5806cfb 100644 --- a/MyBox/src/main/java/mara/mybox/image/ImageValueTools.java +++ b/MyBox/src/main/java/mara/mybox/image/ImageValue.java @@ -18,7 +18,7 @@ import javax.imageio.ImageWriteParam; import javax.imageio.ImageWriter; import javax.imageio.spi.IIORegistry; -import static mara.mybox.imagefile.ImageJpegFile.getJpegCompressionTypes; +import static mara.mybox.image.file.ImageJpegFile.getJpegCompressionTypes; import org.apache.pdfbox.rendering.ImageType; @@ -28,7 +28,7 @@ * @Description * @License Apache License Version 2.0 */ -public class ImageValueTools { +public class ImageValue { // dpi(dot per inch) convert to dpm(dot per millimeter) public static int dpi2dpmm(int dpi) { diff --git a/MyBox/src/main/java/mara/mybox/image/PixelsOperation.java b/MyBox/src/main/java/mara/mybox/image/PixelsOperation.java new file mode 100644 index 000000000..19edecf1b --- /dev/null +++ b/MyBox/src/main/java/mara/mybox/image/PixelsOperation.java @@ -0,0 +1,749 @@ +package mara.mybox.image; + +import java.awt.Color; +import java.awt.image.BufferedImage; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.data.IntPoint; + +/** + * @Author Mara + * @CreateDate 2019-2-13 14:44:03 + * @Version 1.0 + * @Description + * @License Apache License Version 2.0 + */ +public class PixelsOperation { + + protected BufferedImage image; + protected boolean isDithering, boolPara; + protected int intPara1, intPara2, intPara3; + protected float floatPara1, floatPara2; + protected Color colorPara1, colorPara2; + protected ImageScope scope; + protected OperationType operationType; + protected ColorActionType colorActionType; + + protected Color[] thisLine, nextLine; + protected int thisLineY; + protected int imageWidth, imageHeight; + + public enum OperationType { + Blur, Sharpen, Clarity, Emboss, EdgeDetect, Thresholding, Quantization, Gray, BlackOrWhite, Sepia, + ReplaceColor, Invert, Red, Green, Blue, Yellow, Cyan, Magenta, + Brightness, Sauration, Hue, Opacity, RGB, Color, Scope, Convolution, Contrast + } + + public enum ColorActionType { + Increase, Decrease, Set, Filter, Invert + } + + public PixelsOperation() { + + } + + public PixelsOperation(BufferedImage image) { + this.image = image; + } + + public PixelsOperation(BufferedImage image, OperationType operationType) { + this.image = image; + this.operationType = operationType; + this.scope = null; + } + + public PixelsOperation(BufferedImage image, ImageScope scope, OperationType operationType) { + this.image = image; + this.operationType = operationType; + this.scope = scope; + } + + public PixelsOperation(BufferedImage image, ImageScope scope, + OperationType operationType, ColorActionType colorActionType) { + this.image = image; + this.operationType = operationType; + this.scope = scope; + this.colorActionType = colorActionType; + } + + public BufferedImage operate() { + return operationImage(); + } + + public BufferedImage operationImage() { + if (image == null || operationType == null) { + return image; + } + imageWidth = image.getWidth(); + imageHeight = image.getHeight(); + if (operationType != OperationType.BlackOrWhite + && operationType != OperationType.Quantization) { + isDithering = false; + } + if (scope != null && scope.getScopeType() == ImageScope.ScopeType.Matting) { + isDithering = false; + return operateMatting(); + } else { + return operateScope(); + } + } + + protected BufferedImage operateScope() { + if (image == null) { + return image; + } + try { + int imageType = image.getType(); + if (imageType == BufferedImage.TYPE_CUSTOM) { + imageType = BufferedImage.TYPE_INT_ARGB; + } + BufferedImage target = new BufferedImage(imageWidth, imageHeight, imageType); + boolean isScope = (operationType == OperationType.Scope); + boolean isWhole = (scope == null || scope.getScopeType() == ImageScope.ScopeType.All); + boolean inScope; + if (isDithering) { + thisLine = new Color[imageWidth]; + nextLine = new Color[imageWidth]; + thisLineY = 0; + thisLine[0] = new Color(image.getRGB(0, 0), true); + } + for (int y = 0; y < image.getHeight(); y++) { + for (int x = 0; x < image.getWidth(); x++) { + Color color = new Color(image.getRGB(x, y), true); + inScope = isWhole || scope.inScope(x, y, color); + if (isScope) { + if (inScope) { + if (isDithering && y == thisLineY) { + color = thisLine[x]; + } + target.setRGB(x, y, color.getRGB()); + } else { + operatePixel(target, color, x, y); + } + } else { + if (inScope) { + operatePixel(target, color, x, y); + } else { + if (isDithering && y == thisLineY) { + color = thisLine[x]; + } + target.setRGB(x, y, color.getRGB()); + } + } + } + if (isDithering) { + thisLine = nextLine; + thisLineY = y + 1; + nextLine = new Color[imageWidth]; + } + } + thisLine = nextLine = null; + return target; + } catch (Exception e) { + logger.error(e.toString()); + return image; + } + } + + // https://en.wikipedia.org/wiki/Flood_fill + // https://www.codeproject.com/Articles/6017/QuickFill-An-Efficient-Flood-Fill-Algorithm + protected BufferedImage operateMatting() { + try { + if (image == null || scope == null) { + return image; + } + List points = scope.getPoints(); + if (points == null || points.isEmpty()) { + return image; + } + int imageType = image.getType(); + if (imageType == BufferedImage.TYPE_CUSTOM) { + imageType = BufferedImage.TYPE_INT_ARGB; + } + BufferedImage target = new BufferedImage(imageWidth, imageHeight, imageType); + boolean excluded = scope.isColorExcluded(); + boolean isScope = operationType == OperationType.Scope; + if (isScope) { + if (excluded) { + target = image.getSubimage(0, 0, imageWidth, imageHeight); + } else { + for (int y = 0; y < imageHeight; y++) { + for (int x = 0; x < imageWidth; x++) { + operatePixel(target, x, y); + } + } + } + } else { + if (excluded) { + for (int y = 0; y < imageHeight; y++) { + for (int x = 0; x < imageWidth; x++) { + operatePixel(target, x, y); + } + } + } else { + target = image.getSubimage(0, 0, imageWidth, imageHeight); + } + } + + boolean[][] visited = new boolean[imageHeight][imageWidth]; + Queue queue = new LinkedList<>(); + for (IntPoint point : points) { + Color startColor = new Color(image.getRGB(point.getX(), point.getY()), true); + queue.add(point); + while (!queue.isEmpty()) { + IntPoint p = queue.remove(); + int x = p.getX(), y = p.getY(); + if (x < 0 || x >= imageWidth || y < 0 || y >= imageHeight + || visited[y][x]) { + continue; + } + visited[y][x] = true; + int pixel = image.getRGB(x, y); + Color color = new Color(pixel, true); + if (scope.inColorMatch(startColor, color)) { + if (isScope) { + if (excluded) { + operatePixel(target, color, x, y); + } else { + target.setRGB(x, y, pixel); + } + } else { + if (excluded) { + target.setRGB(x, y, pixel); + } else { + operatePixel(target, color, x, y); + } + } + + queue.add(new IntPoint(x + 1, y)); + queue.add(new IntPoint(x - 1, y)); + queue.add(new IntPoint(x, y + 1)); + queue.add(new IntPoint(x, y - 1)); + } + } + } + return target; + } catch (Exception e) { + logger.error(e.toString()); + return null; + } + } + + protected void operatePixel(BufferedImage target, int x, int y) { + operatePixel(target, image.getRGB(x, y), x, y); + } + + protected void operatePixel(BufferedImage target, int pixel, int x, int y) { + operatePixel(target, new Color(pixel, true), x, y); + } + + protected void operatePixel(BufferedImage target, Color inColor, int x, int y) { + Color color; + if (isDithering && y == thisLineY) { + color = thisLine[x]; + } else { + color = inColor; + } + Color newColor = operateColor(color); + target.setRGB(x, y, newColor.getRGB()); + + dithering(target, color, newColor, x, y); + + } + + // https://en.wikipedia.org/wiki/Dither + // https://en.wikipedia.org/wiki/Floyd%E2%80%93Steinberg_dithering + protected void dithering(BufferedImage target, Color color, Color newColor, int x, int y) { + if (!isDithering || y != thisLineY) { + return; + } + int red_error, green_error, blue_error; + int new_red, new_green, new_blue; + red_error = color.getRed() - newColor.getRed(); + green_error = color.getGreen() - newColor.getGreen(); + blue_error = color.getBlue() - newColor.getBlue(); + + if (x + 1 < imageWidth) { + color = new Color(image.getRGB(x + 1, y), true); + new_red = Math.max(Math.min(color.getRed() + red_error * 7 / 16, 255), 0); + new_green = Math.max(Math.min(color.getGreen() + green_error * 7 / 16, 255), 0); + new_blue = Math.max(Math.min(color.getBlue() + blue_error * 7 / 16, 255), 0); + newColor = new Color(new_red, new_green, new_blue, color.getAlpha()); + thisLine[x + 1] = newColor; + } + + if (x - 1 >= 0 && y + 1 < imageHeight) { + color = new Color(image.getRGB(x - 1, y + 1), true); + new_red = Math.max(Math.min(color.getRed() + red_error * 3 / 16, 255), 0); + new_green = Math.max(Math.min(color.getGreen() + green_error * 3 / 16, 255), 0); + new_blue = Math.max(Math.min(color.getBlue() + blue_error * 3 / 16, 255), 0); + newColor = new Color(new_red, new_green, new_blue, color.getAlpha()); + nextLine[x - 1] = newColor; + } + + if (y + 1 < imageHeight) { + color = new Color(image.getRGB(x, y + 1), true); + new_red = Math.max(Math.min(color.getRed() + red_error * 5 / 16, 255), 0); + new_green = Math.max(Math.min(color.getGreen() + green_error * 5 / 16, 255), 0); + new_blue = Math.max(Math.min(color.getBlue() + blue_error * 5 / 16, 255), 0); + newColor = new Color(new_red, new_green, new_blue, color.getAlpha()); + nextLine[x] = newColor; + } + + if (x + 1 < imageWidth && y + 1 < imageHeight) { + color = new Color(image.getRGB(x + 1, y + 1), true); + new_red = Math.max(Math.min(color.getRed() + red_error * 1 / 16, 255), 0); + new_green = Math.max(Math.min(color.getGreen() + green_error * 1 / 16, 255), 0); + new_blue = Math.max(Math.min(color.getBlue() + blue_error * 1 / 16, 255), 0); + newColor = new Color(new_red, new_green, new_blue, color.getAlpha()); + nextLine[x + 1] = newColor; + } + + } + + protected Color operateColor(Color color) { + if (operationType == null) { + return color; + } + Color newColor = color; + float f; + int red, blue, green, opacity; + float[] hsb; + switch (operationType) { + case Convolution: + break; + case Scope: + newColor = new Color(color.getRed(), color.getGreen(), color.getBlue(), (int) (scope.getOpacity() * 255)); + break; + case Sepia: + newColor = ImageColor.pixel2Sepia(color, intPara1); + break; + case Thresholding: + newColor = ImageColor.thresholdingColor(color, intPara1, intPara2, intPara3); + break; + case ReplaceColor: + if (scope.inColorMatch(color, colorPara1)) { + newColor = colorPara2; + } + break; + case Color: + newColor = colorPara1; + break; + case Brightness: + hsb = ImageColor.getHSB(color); + switch (colorActionType) { + case Increase: + f = hsb[2] * (1.0f + floatPara1); + break; + case Decrease: + f = hsb[2] * (1.0f - floatPara1); + break; + case Set: + default: + f = floatPara1; + break; + } + f = Math.min(Math.max(f, 0.0f), 1.0f); + newColor = ImageColor.HSB2RGB(hsb[0], hsb[1], f); + break; + case Sauration: + hsb = ImageColor.getHSB(color); + switch (colorActionType) { + case Increase: + f = hsb[1] * (1.0f + floatPara1); + break; + case Decrease: + f = hsb[1] * (1.0f - floatPara1); + break; + case Set: + default: + f = floatPara1; + break; + } + f = Math.min(Math.max(f, 0.0f), 1.0f); + newColor = ImageColor.HSB2RGB(hsb[0], f, hsb[2]); + break; + case Hue: + hsb = ImageColor.getHSB(color); + switch (colorActionType) { + case Increase: + f = hsb[0] + floatPara1; + break; + case Decrease: + f = hsb[0] - floatPara1; + break; + case Set: + default: + f = floatPara1; + break; + } + if (f > 1.0f) { + f = f - 1.0f; + } + if (f < 0.0f) { + f = f + 1.0f; + } + f = Math.min(Math.max(f, 0.0f), 1.0f); + newColor = ImageColor.HSB2RGB(f, hsb[1], hsb[2]); + break; + case Opacity: + opacity = Math.min(Math.max(intPara1, 0), 255); + newColor = new Color(color.getRed(), color.getGreen(), color.getBlue(), opacity); + break; + case Red: + switch (colorActionType) { + case Set: + red = intPara1; + red = Math.min(Math.max(red, 0), 255); + newColor = new Color(red, color.getGreen(), color.getBlue(), color.getAlpha()); + break; + case Increase: + red = color.getRed() + intPara1; + red = Math.min(Math.max(red, 0), 255); + newColor = new Color(red, color.getGreen(), color.getBlue(), color.getAlpha()); + break; + case Decrease: + red = color.getRed() - intPara1; + red = Math.min(Math.max(red, 0), 255); + newColor = new Color(red, color.getGreen(), color.getBlue(), color.getAlpha()); + break; + case Filter: + newColor = new Color(color.getRed(), 0, 0, color.getAlpha()); + break; + case Invert: + newColor = new Color(255 - color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); + break; + } + break; + case Green: + switch (colorActionType) { + case Set: + green = intPara1; + green = Math.min(Math.max(green, 0), 255); + newColor = new Color(color.getRed(), green, color.getBlue(), color.getAlpha()); + break; + case Increase: + green = color.getGreen() + intPara1; + green = Math.min(Math.max(green, 0), 255); + newColor = new Color(color.getRed(), green, color.getBlue(), color.getAlpha()); + break; + case Decrease: + green = color.getGreen() - intPara1; + green = Math.min(Math.max(green, 0), 255); + newColor = new Color(color.getRed(), green, color.getBlue(), color.getAlpha()); + break; + case Filter: + newColor = new Color(0, color.getGreen(), 0, color.getAlpha()); + break; + case Invert: + newColor = new Color(color.getRed(), 255 - color.getGreen(), color.getBlue(), color.getAlpha()); + break; + } + break; + case Blue: + switch (colorActionType) { + case Set: + blue = intPara1; + blue = Math.min(Math.max(blue, 0), 255); + newColor = new Color(color.getRed(), color.getGreen(), blue, color.getAlpha()); + break; + case Increase: + blue = color.getBlue() + intPara1; + blue = Math.min(Math.max(blue, 0), 255); + newColor = new Color(color.getRed(), color.getGreen(), blue, color.getAlpha()); + break; + case Decrease: + blue = color.getBlue() - intPara1; + blue = Math.min(Math.max(blue, 0), 255); + newColor = new Color(color.getRed(), color.getGreen(), blue, color.getAlpha()); + break; + case Filter: + newColor = new Color(0, 0, color.getBlue(), color.getAlpha()); + break; + case Invert: + newColor = new Color(color.getRed(), color.getGreen(), 255 - color.getBlue(), color.getAlpha()); + break; + } + break; + case Yellow: + switch (colorActionType) { + case Set: + red = intPara1; + green = intPara1; + red = Math.min(Math.max(red, 0), 255); + green = Math.min(Math.max(green, 0), 255); + newColor = new Color(red, green, color.getBlue(), color.getAlpha()); + break; + case Increase: + red = color.getRed() + intPara1; + green = color.getGreen() + intPara1; + red = Math.min(Math.max(red, 0), 255); + green = Math.min(Math.max(green, 0), 255); + newColor = new Color(red, green, color.getBlue(), color.getAlpha()); + break; + case Decrease: + red = color.getRed() - intPara1; + green = color.getGreen() - intPara1; + red = Math.min(Math.max(red, 0), 255); + green = Math.min(Math.max(green, 0), 255); + newColor = new Color(red, green, color.getBlue(), color.getAlpha()); + break; + case Filter: + newColor = new Color(color.getRed(), color.getGreen(), 0, color.getAlpha()); + break; + case Invert: + newColor = new Color(255 - color.getRed(), 255 - color.getGreen(), color.getBlue(), color.getAlpha()); + break; + } + break; + case Cyan: + switch (colorActionType) { + case Set: + blue = intPara1; + green = intPara1; + blue = Math.min(Math.max(blue, 0), 255); + green = Math.min(Math.max(green, 0), 255); + newColor = new Color(color.getRed(), green, blue, color.getAlpha()); + break; + case Increase: + blue = color.getBlue() + intPara1; + green = color.getGreen() + intPara1; + blue = Math.min(Math.max(blue, 0), 255); + green = Math.min(Math.max(green, 0), 255); + newColor = new Color(color.getRed(), green, blue, color.getAlpha()); + break; + case Decrease: + blue = color.getBlue() - intPara1; + green = color.getGreen() - intPara1; + blue = Math.min(Math.max(blue, 0), 255); + green = Math.min(Math.max(green, 0), 255); + newColor = new Color(color.getRed(), green, blue, color.getAlpha()); + break; + case Filter: + newColor = new Color(0, color.getGreen(), color.getBlue(), color.getAlpha()); + break; + case Invert: + newColor = new Color(color.getRed(), 255 - color.getGreen(), 255 - color.getBlue(), color.getAlpha()); + break; + } + break; + case Magenta: + switch (colorActionType) { + case Set: + blue = intPara1; + red = intPara1; + blue = Math.min(Math.max(blue, 0), 255); + red = Math.min(Math.max(red, 0), 255); + newColor = new Color(red, color.getGreen(), blue, color.getAlpha()); + break; + case Increase: + blue = color.getBlue() + intPara1; + red = color.getRed() + intPara1; + blue = Math.min(Math.max(blue, 0), 255); + red = Math.min(Math.max(red, 0), 255); + newColor = new Color(red, color.getGreen(), blue, color.getAlpha()); + break; + case Decrease: + blue = color.getBlue() - intPara1; + red = color.getRed() - intPara1; + blue = Math.min(Math.max(blue, 0), 255); + red = Math.min(Math.max(red, 0), 255); + newColor = new Color(red, color.getGreen(), blue, color.getAlpha()); + break; + case Filter: + newColor = new Color(color.getRed(), 0, color.getBlue(), color.getAlpha()); + break; + case Invert: + newColor = new Color(255 - color.getRed(), color.getGreen(), 255 - color.getBlue(), color.getAlpha()); + break; + } + break; + case RGB: + switch (colorActionType) { + case Set: + blue = intPara1; + green = intPara1; + red = intPara1; + blue = Math.min(Math.max(blue, 0), 255); + green = Math.min(Math.max(green, 0), 255); + red = Math.min(Math.max(red, 0), 255); + newColor = new Color(red, green, blue, color.getAlpha()); + break; + case Increase: + blue = color.getBlue() + intPara1; + green = color.getGreen() + intPara1; + red = color.getRed() + intPara1; + blue = Math.min(Math.max(blue, 0), 255); + green = Math.min(Math.max(green, 0), 255); + red = Math.min(Math.max(red, 0), 255); + newColor = new Color(red, green, blue, color.getAlpha()); + break; + case Decrease: + blue = color.getBlue() - intPara1; + green = color.getGreen() - intPara1; + red = color.getRed() - intPara1; + blue = Math.min(Math.max(blue, 0), 255); + green = Math.min(Math.max(green, 0), 255); + red = Math.min(Math.max(red, 0), 255); + newColor = new Color(red, green, blue, color.getAlpha()); + break; + case Invert: + newColor = new Color(255 - color.getRed(), 255 - color.getGreen(), 255 - color.getBlue(), color.getAlpha()); + break; + } + break; + + default: + break; + } + return newColor; + + } + + public BufferedImage getImage() { + return image; + } + + public void setImage(BufferedImage image) { + this.image = image; + } + + public boolean isIsDithering() { + return isDithering; + } + + public void setIsDithering(boolean isDithering) { + this.isDithering = isDithering; + } + + public boolean isBoolPara() { + return boolPara; + } + + public void setBoolPara(boolean boolPara) { + this.boolPara = boolPara; + } + + public int getIntPara1() { + return intPara1; + } + + public void setIntPara1(int intPara1) { + this.intPara1 = intPara1; + } + + public int getIntPara2() { + return intPara2; + } + + public void setIntPara2(int intPara2) { + this.intPara2 = intPara2; + } + + public int getIntPara3() { + return intPara3; + } + + public void setIntPara3(int intPara3) { + this.intPara3 = intPara3; + } + + public float getFloatPara1() { + return floatPara1; + } + + public void setFloatPara1(float floatPara1) { + this.floatPara1 = floatPara1; + } + + public float getFloatPara2() { + return floatPara2; + } + + public void setFloatPara2(float floatPara2) { + this.floatPara2 = floatPara2; + } + + public ImageScope getScope() { + return scope; + } + + public void setScope(ImageScope scope) { + this.scope = scope; + } + + public OperationType getOperationType() { + return operationType; + } + + public void setOperationType(OperationType operationType) { + this.operationType = operationType; + } + + public Color[] getThisLine() { + return thisLine; + } + + public void setThisLine(Color[] thisLine) { + this.thisLine = thisLine; + } + + public Color[] getNextLine() { + return nextLine; + } + + public void setNextLine(Color[] nextLine) { + this.nextLine = nextLine; + } + + public int getThisLineY() { + return thisLineY; + } + + public void setThisLineY(int thisLineY) { + this.thisLineY = thisLineY; + } + + public int getImageWidth() { + return imageWidth; + } + + public void setImageWidth(int imageWidth) { + this.imageWidth = imageWidth; + } + + public int getImageHeight() { + return imageHeight; + } + + public void setImageHeight(int imageHeight) { + this.imageHeight = imageHeight; + } + + public Color getColorPara1() { + return colorPara1; + } + + public void setColorPara1(Color colorPara1) { + this.colorPara1 = colorPara1; + } + + public Color getColorPara2() { + return colorPara2; + } + + public void setColorPara2(Color colorPara2) { + this.colorPara2 = colorPara2; + } + + public ColorActionType getColorActionType() { + return colorActionType; + } + + public void setColorActionType(ColorActionType colorActionType) { + this.colorActionType = colorActionType; + } + +} diff --git a/MyBox/src/main/java/mara/mybox/imagefile/ImageBmpFile.java b/MyBox/src/main/java/mara/mybox/image/file/ImageBmpFile.java similarity index 93% rename from MyBox/src/main/java/mara/mybox/imagefile/ImageBmpFile.java rename to MyBox/src/main/java/mara/mybox/image/file/ImageBmpFile.java index c021ce919..99b32f5a6 100644 --- a/MyBox/src/main/java/mara/mybox/imagefile/ImageBmpFile.java +++ b/MyBox/src/main/java/mara/mybox/image/file/ImageBmpFile.java @@ -1,6 +1,6 @@ -package mara.mybox.imagefile; +package mara.mybox.image.file; -import mara.mybox.image.ImageValueTools; +import mara.mybox.image.ImageValue; import com.github.jaiimageio.impl.plugins.bmp.BMPImageReader; import com.github.jaiimageio.impl.plugins.bmp.BMPImageReaderSpi; import com.github.jaiimageio.impl.plugins.bmp.BMPImageWriter; @@ -17,11 +17,10 @@ import javax.imageio.metadata.IIOMetadataNode; import javax.imageio.stream.ImageInputStream; import javax.imageio.stream.ImageOutputStream; -import mara.mybox.objects.ImageAttributes; -import static mara.mybox.image.ImageValueTools.dpi2dpm; -import mara.mybox.objects.ImageInformation; - -import static mara.mybox.objects.AppVaribles.logger; +import mara.mybox.data.ImageAttributes; +import static mara.mybox.image.ImageValue.dpi2dpm; +import mara.mybox.data.ImageInformation; +import static mara.mybox.value.AppVaribles.logger; /** @@ -134,13 +133,13 @@ public static void explainBmpMetaData(Map X = javax_imageio_bmp.get("X"); if (X.containsKey("value")) { - info.setwDensity(ImageValueTools.dpm2dpi(Integer.valueOf(X.get("value")))); + info.setwDensity(ImageValue.dpm2dpi(Integer.valueOf(X.get("value")))); } } if (javax_imageio_bmp.containsKey("Y")) { // PixelsPerMeter Map Y = javax_imageio_bmp.get("Y"); if (Y.containsKey("value")) { - info.sethDensity(ImageValueTools.dpm2dpi(Integer.valueOf(Y.get("value")))); + info.sethDensity(ImageValue.dpm2dpi(Integer.valueOf(Y.get("value")))); } } if (javax_imageio_bmp.containsKey("BitsPerPixel")) { diff --git a/MyBox/src/main/java/mara/mybox/imagefile/ImageFileReaders.java b/MyBox/src/main/java/mara/mybox/image/file/ImageFileReaders.java similarity index 98% rename from MyBox/src/main/java/mara/mybox/imagefile/ImageFileReaders.java rename to MyBox/src/main/java/mara/mybox/image/file/ImageFileReaders.java index de84aa969..8cc117f99 100644 --- a/MyBox/src/main/java/mara/mybox/imagefile/ImageFileReaders.java +++ b/MyBox/src/main/java/mara/mybox/image/file/ImageFileReaders.java @@ -1,4 +1,4 @@ -package mara.mybox.imagefile; +package mara.mybox.image.file; import java.awt.Rectangle; import java.awt.color.ColorSpace; @@ -17,19 +17,19 @@ import javax.imageio.ImageTypeSpecifier; import javax.imageio.metadata.IIOMetadata; import javax.imageio.stream.ImageInputStream; -import mara.mybox.fxml.FxmlImageTools; -import mara.mybox.objects.ImageFileInformation; -import mara.mybox.image.ImageColorTools; +import mara.mybox.fxml.image.ImageTools; +import mara.mybox.data.ImageFileInformation; +import mara.mybox.image.ImageColor; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.logger; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; -import static mara.mybox.image.ImageValueTools.pixelSizeMm2dpi; -import static mara.mybox.imagefile.ImageGifFile.readBrokenGifFile; -import static mara.mybox.imagefile.ImageGifFile.readBrokenGifFileWithWidth; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.ImageInformation; +import static mara.mybox.image.ImageValue.pixelSizeMm2dpi; +import static mara.mybox.image.file.ImageGifFile.readBrokenGifFile; +import static mara.mybox.image.file.ImageGifFile.readBrokenGifFileWithWidth; +import mara.mybox.value.AppVaribles; +import mara.mybox.data.ImageInformation; /** * @Author Mara @@ -343,7 +343,7 @@ public static BufferedImage getBufferedImage(ImageInformation imageInfo) { if (imageInfo.getBufferedImage() != null) { bufferedImage = imageInfo.getBufferedImage(); } else if (imageInfo.getImage() != null) { - bufferedImage = FxmlImageTools.getBufferedImage(imageInfo.getImage()); + bufferedImage = ImageTools.getBufferedImage(imageInfo.getImage()); } } if (bufferedImage == null) { @@ -575,7 +575,7 @@ public static ImageFileInformation readImageFileMetaData(String fileName) { try { ColorModel cm = typesValue.get(0).getColorModel(); ColorSpace cs = cm.getColorSpace(); - imageInfo.setColorSpace(ImageColorTools.getColorSpaceName(cs.getType())); + imageInfo.setColorSpace(ImageColor.getColorSpaceName(cs.getType())); imageInfo.setColorChannels(cm.getNumComponents()); imageInfo.setBitDepth(cm.getPixelSize() + ""); } catch (Exception e) { diff --git a/MyBox/src/main/java/mara/mybox/imagefile/ImageFileWriters.java b/MyBox/src/main/java/mara/mybox/image/file/ImageFileWriters.java similarity index 85% rename from MyBox/src/main/java/mara/mybox/imagefile/ImageFileWriters.java rename to MyBox/src/main/java/mara/mybox/image/file/ImageFileWriters.java index 5c8ac4dec..e76ef573a 100644 --- a/MyBox/src/main/java/mara/mybox/imagefile/ImageFileWriters.java +++ b/MyBox/src/main/java/mara/mybox/image/file/ImageFileWriters.java @@ -1,4 +1,4 @@ -package mara.mybox.imagefile; +package mara.mybox.image.file; import com.github.jaiimageio.plugins.bmp.BMPImageWriteParam; import com.github.jaiimageio.impl.plugins.bmp.BMPImageWriter; @@ -22,18 +22,19 @@ import javax.imageio.metadata.IIOMetadataNode; import javax.imageio.plugins.jpeg.JPEGImageWriteParam; import javax.imageio.stream.ImageOutputStream; -import mara.mybox.image.ImageConvertTools; -import mara.mybox.image.ImageGrayTools; -import mara.mybox.objects.ImageAttributes; -import static mara.mybox.imagefile.ImageBmpFile.writeBmpImageFile; -import static mara.mybox.imagefile.ImageJpegFile.writeJPEGImageFile; -import static mara.mybox.imagefile.ImagePngFile.writePNGImageFile; -import static mara.mybox.imagefile.ImageRawFile.writeRawImageFile; -import static mara.mybox.imagefile.ImagePcxFile.writePcxImageFile; +import mara.mybox.image.ImageBinary; +import mara.mybox.image.ImageConvert; +import mara.mybox.image.PixelsOperation; +import mara.mybox.data.ImageAttributes; +import static mara.mybox.image.file.ImageBmpFile.writeBmpImageFile; +import static mara.mybox.image.file.ImageJpegFile.writeJPEGImageFile; +import static mara.mybox.image.file.ImagePngFile.writePNGImageFile; +import static mara.mybox.image.file.ImageRawFile.writeRawImageFile; +import static mara.mybox.image.file.ImagePcxFile.writePcxImageFile; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.logger; -import static mara.mybox.imagefile.ImageTiffFile.writeTiffImage; +import static mara.mybox.image.file.ImageTiffFile.writeTiffImage; import org.apache.pdfbox.rendering.ImageType; /** @@ -46,8 +47,6 @@ // https://docs.oracle.com/javase/10/docs/api/javax/imageio/metadata/doc-files/standard_metadata.html public class ImageFileWriters { - - public static boolean writeImageFile(BufferedImage image, String format, String outFile) { if (image == null || outFile == null || format == null) { return false; @@ -92,7 +91,7 @@ public static boolean writeImageFile(BufferedImage image, File file; try { format = attributes.getImageFormat().toLowerCase(); - image = ImageConvertTools.checkAlpha(image, format); + image = ImageConvert.checkAlpha(image, format); file = new File(outFile); if (file.exists()) { @@ -269,11 +268,6 @@ public static boolean writeCommonImageFile(BufferedImage image, return false; } } -// Element tree = (Element) metaData.getAsTree(format); -// Element HorizontalPixelSize = (Element) tree.getElementsByTagName("HorizontalPixelSize").item(0); -// HorizontalPixelSize.setAttribute("value", pixelSizeMm + ""); -// Element VerticalPixelSize = (Element) tree.getElementsByTagName("VerticalPixelSize").item(0); -// VerticalPixelSize.setAttribute("value", pixelSizeMm + ""); public static BufferedImage convertColor(BufferedImage bufferedImage, ImageAttributes attributes) { try { @@ -282,20 +276,34 @@ public static BufferedImage convertColor(BufferedImage bufferedImage, ImageAttri } int color = bufferedImage.getType(); if (ImageType.BINARY == attributes.getColorSpace()) { + ImageBinary imageBinary; if (attributes.getBinaryConversion() == ImageAttributes.BinaryConversion.BINARY_THRESHOLD && attributes.getThreshold() >= 0) { - bufferedImage = ImageGrayTools.color2BinaryWithPercentage(bufferedImage, attributes.getThreshold()); + imageBinary = new ImageBinary(bufferedImage, attributes.getThreshold()); + imageBinary.setIsDithering(attributes.isIsDithering()); + bufferedImage = imageBinary.operate(); + bufferedImage = ImageBinary.byteBinary(bufferedImage); } else if (attributes.getBinaryConversion() == ImageAttributes.BinaryConversion.BINARY_OTSU) { - bufferedImage = ImageGrayTools.color2BinaryByCalculation(bufferedImage); + imageBinary = new ImageBinary(bufferedImage, -1); + imageBinary.setCalculate(true); + imageBinary.setIsDithering(attributes.isIsDithering()); + bufferedImage = imageBinary.operate(); + bufferedImage = ImageBinary.byteBinary(bufferedImage); + + } else if (color != BufferedImage.TYPE_BYTE_BINARY || attributes.isIsDithering()) { + imageBinary = new ImageBinary(bufferedImage, -1); + imageBinary.setIsDithering(attributes.isIsDithering()); + bufferedImage = imageBinary.operate(); + bufferedImage = ImageBinary.byteBinary(bufferedImage); - } else if (color != BufferedImage.TYPE_BYTE_BINARY) { - bufferedImage = ImageGrayTools.color2Binary(bufferedImage); } } else if (ImageType.GRAY == attributes.getColorSpace() && color != BufferedImage.TYPE_BYTE_GRAY) { - bufferedImage = ImageGrayTools.color2Gray(bufferedImage); + ImageBinary imageBinary = new ImageBinary(bufferedImage, PixelsOperation.OperationType.Gray); + bufferedImage = imageBinary.operate(); + } else if (ImageType.RGB == attributes.getColorSpace()) { - bufferedImage = ImageConvertTools.clearAlpha(bufferedImage); + bufferedImage = ImageConvert.clearAlpha(bufferedImage); } return bufferedImage; } catch (Exception e) { diff --git a/MyBox/src/main/java/mara/mybox/imagefile/ImageGifFile.java b/MyBox/src/main/java/mara/mybox/image/file/ImageGifFile.java similarity index 95% rename from MyBox/src/main/java/mara/mybox/imagefile/ImageGifFile.java rename to MyBox/src/main/java/mara/mybox/image/file/ImageGifFile.java index 0b4b29c03..c34a4aadb 100644 --- a/MyBox/src/main/java/mara/mybox/imagefile/ImageGifFile.java +++ b/MyBox/src/main/java/mara/mybox/image/file/ImageGifFile.java @@ -1,4 +1,4 @@ -package mara.mybox.imagefile; +package mara.mybox.image.file; import com.github.jaiimageio.impl.plugins.gif.GIFImageMetadata; import com.github.jaiimageio.impl.plugins.gif.GIFImageWriter; @@ -19,14 +19,14 @@ import javax.imageio.metadata.IIOMetadataNode; import javax.imageio.stream.ImageInputStream; import javax.imageio.stream.ImageOutputStream; -import mara.mybox.image.ImageConvertTools; -import static mara.mybox.imagefile.ImageFileReaders.needSampled; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.ImageAttributes; -import mara.mybox.objects.ImageInformation; +import mara.mybox.image.ImageConvert; +import static mara.mybox.image.file.ImageFileReaders.needSampled; +import mara.mybox.value.CommonValues; +import mara.mybox.data.ImageAttributes; +import mara.mybox.data.ImageInformation; import mara.mybox.tools.FileTools; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.logger; import mara.mybox.tools.ValueTools; import thridparty.GifDecoder; @@ -128,7 +128,7 @@ public static List readBrokenGifFileWithWidth(String src, int wid final int frameCount = gif.getFrameCount(); for (int i = 0; i < frameCount; i++) { final BufferedImage img = gif.getFrame(i); - images.add(ImageConvertTools.scaleImageWidthKeep(img, width)); + images.add(ImageConvert.scaleImageWidthKeep(img, width)); } } return images; @@ -151,7 +151,7 @@ public static List readBrokenGifFile(String src, List extractGifImages(File source, File target, int digit = (size + "").length(); List names = new ArrayList<>(); for (int i = from; i <= to; i++) { - filename = filePrefix + "-" + ValueTools.fillNumber(i, digit) + "." + format; + filename = filePrefix + "-" + ValueTools.fillLeftZero(i, digit) + "." + format; ImageFileWriters.writeImageFile(images.get(i), format, filename); names.add(filename); } @@ -393,7 +393,7 @@ public static String writeImages(List imagesInfo, BufferedImage bufferedImage = ImageFileReaders.getBufferedImage(info); if (bufferedImage != null) { if (!keepSize) { - bufferedImage = ImageConvertTools.scaleImage(bufferedImage, width, height); + bufferedImage = ImageConvert.scaleImage(bufferedImage, width, height); } gifWriter.writeToSequence(new IIOImage(bufferedImage, null, metaData), param); } diff --git a/MyBox/src/main/java/mara/mybox/imagefile/ImageJpegFile.java b/MyBox/src/main/java/mara/mybox/image/file/ImageJpegFile.java similarity index 92% rename from MyBox/src/main/java/mara/mybox/imagefile/ImageJpegFile.java rename to MyBox/src/main/java/mara/mybox/image/file/ImageJpegFile.java index 69e936a9e..888621e12 100644 --- a/MyBox/src/main/java/mara/mybox/imagefile/ImageJpegFile.java +++ b/MyBox/src/main/java/mara/mybox/image/file/ImageJpegFile.java @@ -1,6 +1,6 @@ -package mara.mybox.imagefile; +package mara.mybox.image.file; -import mara.mybox.image.ImageValueTools; +import mara.mybox.image.ImageValue; import java.awt.image.BufferedImage; import java.io.File; import java.util.Map; @@ -12,10 +12,9 @@ import javax.imageio.metadata.IIOMetadata; import javax.imageio.plugins.jpeg.JPEGImageWriteParam; import javax.imageio.stream.ImageOutputStream; -import mara.mybox.objects.ImageAttributes; -import mara.mybox.objects.ImageInformation; - -import static mara.mybox.objects.AppVaribles.logger; +import mara.mybox.data.ImageAttributes; +import mara.mybox.data.ImageInformation; +import static mara.mybox.value.AppVaribles.logger; import org.w3c.dom.Element; @@ -105,7 +104,7 @@ public static void explainJpegMetaData(Map splitFileByFilesNumber(File file, while ((fileIndex < filesNumber) && (bufLen = inputStream.read(buf)) != -1) { endIndex += bufLen; - newFilename = filename + "-cut-f" + ValueTools.fillNumber(fileIndex, digit) + newFilename = filename + "-cut-f" + ValueTools.fillLeftZero(fileIndex, digit) + "-b" + (startIndex + 1) + "-b" + endIndex; try (FileOutputStream outputStream = new FileOutputStream(newFilename)) { if (bytesNumber > bufLen) { @@ -508,7 +506,7 @@ public static List splitFileByFilesNumber(File file, bufLen = inputStream.read(buf); if (bufLen > 0) { endIndex += bufLen; - newFilename = filename + "-cut-f" + ValueTools.fillNumber(fileIndex, digit) + newFilename = filename + "-cut-f" + ValueTools.fillLeftZero(fileIndex, digit) + "-b" + (startIndex + 1) + "-b" + endIndex; try (FileOutputStream outputStream = new FileOutputStream(newFilename)) { outputStream.write(buf); @@ -541,7 +539,7 @@ public static List splitFileByBytesNumber(File file, int bufLen, fileIndex = 1, startIndex = 0, endIndex = 0; while ((bufLen = inputStream.read(buf)) != -1) { endIndex += bufLen; - newFilename = filename + "-cut-f" + ValueTools.fillNumber(fileIndex, digit) + newFilename = filename + "-cut-f" + ValueTools.fillLeftZero(fileIndex, digit) + "-b" + (startIndex + 1) + "-b" + endIndex; try (FileOutputStream outputStream = new FileOutputStream(newFilename)) { if (bytesNumber > bufLen) { diff --git a/MyBox/src/main/java/mara/mybox/tools/NetworkTools.java b/MyBox/src/main/java/mara/mybox/tools/NetworkTools.java index e9424f60a..c146ab20f 100644 --- a/MyBox/src/main/java/mara/mybox/tools/NetworkTools.java +++ b/MyBox/src/main/java/mara/mybox/tools/NetworkTools.java @@ -4,8 +4,8 @@ import java.util.HashMap; import java.util.Map; import javafx.scene.web.WebEngine; -import mara.mybox.objects.AppVaribles; -import static mara.mybox.objects.AppVaribles.logger; +import mara.mybox.value.AppVaribles; +import static mara.mybox.value.AppVaribles.logger; /** * @Author Mara diff --git a/MyBox/src/main/java/mara/mybox/tools/PdfTools.java b/MyBox/src/main/java/mara/mybox/tools/PdfTools.java index 476327812..ef5a03b82 100644 --- a/MyBox/src/main/java/mara/mybox/tools/PdfTools.java +++ b/MyBox/src/main/java/mara/mybox/tools/PdfTools.java @@ -1,6 +1,6 @@ package mara.mybox.tools; -import mara.mybox.fxml.FxmlImageTools; +import mara.mybox.fxml.image.ImageTools; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -12,15 +12,15 @@ import javafx.embed.swing.SwingFXUtils; import javafx.scene.image.Image; import javax.imageio.ImageIO; -import mara.mybox.image.ImageConvertTools; -import mara.mybox.image.ImageGrayTools; -import mara.mybox.imagefile.ImageFileReaders; -import mara.mybox.objects.AppVaribles; -import mara.mybox.objects.CommonValues; -import mara.mybox.objects.ImageAttributes; -import mara.mybox.objects.ImageInformation; -import mara.mybox.objects.WeiboSnapParameters; -import static mara.mybox.objects.AppVaribles.logger; +import mara.mybox.image.ImageBinary; +import mara.mybox.image.ImageConvert; +import mara.mybox.image.file.ImageFileReaders; +import mara.mybox.value.AppVaribles; +import mara.mybox.value.CommonValues; +import mara.mybox.data.ImageAttributes; +import mara.mybox.data.ImageInformation; +import mara.mybox.data.WeiboSnapParameters; +import static mara.mybox.value.AppVaribles.logger; import org.apache.pdfbox.cos.COSName; import org.apache.pdfbox.pdmodel.PDDocument; @@ -40,7 +40,6 @@ import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageXYZDestination; import org.apache.pdfbox.rendering.ImageType; import org.apache.pdfbox.rendering.PDFRenderer; -import org.apache.pdfbox.text.PDFTextStripper; /** * @Author Mara @@ -77,25 +76,24 @@ public static boolean writePage(PDDocument document, PDFont font, String sourceFormat, BufferedImage bufferedImage, int index, int total, PdfImageFormat targetFormat, int threshold, int jpegQuality, boolean isImageSize, boolean pageNumber, - int pageWidth, int pageHeight, int marginSize, String header) { + int pageWidth, int pageHeight, int marginSize, String header, boolean dithering) { try { PDImageXObject imageObject; switch (targetFormat) { case Tiff: - if (threshold < 0) { - bufferedImage = ImageGrayTools.color2Binary(bufferedImage); - } else { - bufferedImage = ImageGrayTools.color2BinaryWithPercentage(bufferedImage, threshold); - } + ImageBinary imageBinary = new ImageBinary(bufferedImage, threshold); + imageBinary.setIsDithering(dithering); + bufferedImage = imageBinary.operate(); + bufferedImage = ImageBinary.byteBinary(bufferedImage); imageObject = CCITTFactory.createFromImage(document, bufferedImage); break; case Jpeg: - bufferedImage = ImageConvertTools.checkAlpha(bufferedImage, "jpg"); + bufferedImage = ImageConvert.checkAlpha(bufferedImage, "jpg"); imageObject = JPEGFactory.createFromImage(document, bufferedImage, jpegQuality / 100f); break; default: if (sourceFormat != null) { - bufferedImage = ImageConvertTools.checkAlpha(bufferedImage, sourceFormat); + bufferedImage = ImageConvert.checkAlpha(bufferedImage, sourceFormat); } imageObject = LosslessFactory.createFromImage(document, bufferedImage); break; @@ -166,7 +164,7 @@ public static boolean htmlIntoPdf(List images, File targetFile, boolean i int marginSize = 20, total = images.size(); for (Image image : images) { PDImageXObject imageObject; - bufferedImage = FxmlImageTools.getBufferedImage(image); + bufferedImage = ImageTools.getBufferedImage(image); imageObject = LosslessFactory.createFromImage(document, bufferedImage); if (isImageSize) { pageSize = new PDRectangle(imageObject.getWidth() + marginSize * 2, imageObject.getHeight() + marginSize * 2); @@ -223,7 +221,7 @@ public static boolean imageInPdf(PDDocument document, BufferedImage bufferedImag return writePage(document, font, "png", bufferedImage, pageNumber, totalPage, p.getFormat(), p.getThreshold(), p.getJpegQuality(), p.isIsImageSize(), p.isAddPageNumber(), - p.getPageWidth(), p.getPageHeight(), p.getMarginSize(), p.getTitle()); + p.getPageWidth(), p.getPageHeight(), p.getMarginSize(), p.getTitle(), p.isDithering()); } public static boolean images2Pdf(List images, File targetFile, @@ -252,7 +250,7 @@ public static boolean images2Pdf(List images, File targetFile, bufferedImage = SwingFXUtils.fromFXImage(image, null); break; case Jpeg: - bufferedImage = FxmlImageTools.checkAlpha(image, "jpg"); + bufferedImage = ImageTools.checkAlpha(image, "jpg"); break; default: bufferedImage = SwingFXUtils.fromFXImage(image, null); @@ -400,29 +398,6 @@ public static PDFont getFont(PDDocument document, String name) { return font; } - public static String getTextFromPdf(InputStream fileStream, boolean sort) { - // 开始提取页数 - int startPage = 1; - // 结束提取页数 - String content = null; - PDDocument document = null; - try { - // 加载 pdf 文档 - document = PDDocument.load(fileStream, AppVaribles.PdfMemUsage); - int endPage = null == document ? Integer.MAX_VALUE : document.getNumberOfPages(); - PDFTextStripper stripper = new PDFTextStripper(); - stripper.setSortByPosition(sort); - stripper.setStartPage(startPage); - stripper.setEndPage(endPage); - content = stripper.getText(document); -// log.info("pdf 文件解析,内容为:" + content); - } catch (Exception e) { -// log.error("文件解析异常,信息为: " + e.getMessage()); - } - return content; - - } - public static List getImageListFromPDF(PDDocument document, Integer startPage) throws Exception { List imageList = new ArrayList<>(); if (null != document) { @@ -456,25 +431,6 @@ public static InputStream getImageInputStream(PDImageXObject iamge) throws Excep } - public static void writeInputStream(InputStream imageb, PDImageXObject image) throws Exception { - -// File imgFile = new File("e:\\" + name + "." + image.getSuffix()); -// FileOutputStream fout = new FileOutputStream(imgFile); -// ByteArrayOutputStream os = new ByteArrayOutputStream(); -// ImageIO.write(imageb, image.getSuffix(), os); -// InputStream is = new ByteArrayInputStream(os.toByteArray()); -// int byteCount = 0; -// byte[] bytes = new byte[1024]; -// -// while ((byteCount = is.read(bytes)) > 0) { -// fout.write(bytes, 0, byteCount); -// } -// -// fout.close(); -// -// is.close(); - } - public static boolean writeSplitImages(String sourceFormat, String sourceFile, ImageInformation imageInformation, List rows, List cols, ImageAttributes attributes, File targetFile, @@ -506,7 +462,7 @@ public static boolean writeSplitImages(String sourceFormat, String sourceFile, int x1, y1, x2, y2; BufferedImage wholeSource = null; if (!imageInformation.isIsSampled()) { - wholeSource = FxmlImageTools.getBufferedImage(imageInformation.getImage()); + wholeSource = ImageTools.getBufferedImage(imageInformation.getImage()); } int count = 0; int total = (rows.size() - 1) * (cols.size() - 1); @@ -520,12 +476,12 @@ public static boolean writeSplitImages(String sourceFormat, String sourceFile, if (imageInformation.isIsSampled()) { target = ImageFileReaders.readRectangle(sourceFormat, sourceFile, x1, y1, x2, y2); } else { - target = ImageConvertTools.cropImage(wholeSource, x1, y1, x2, y2); + target = ImageConvert.cropImage(wholeSource, x1, y1, x2, y2); } PdfTools.writePage(document, font, sourceFormat, target, ++count, total, pdfFormat, threshold, jpegQuality, isImageSize, pageNumber, - pageWidth, pageHeight, marginSize, header); + pageWidth, pageHeight, marginSize, header, attributes.isIsDithering()); } } document.save(targetFile); @@ -572,6 +528,7 @@ public static BufferedImage page2image(File file, String password, int page, return image; } } catch (Exception e) { + logger.debug(e.toString()); return null; } } diff --git a/MyBox/src/main/java/mara/mybox/tools/SoundTools.java b/MyBox/src/main/java/mara/mybox/tools/SoundTools.java index ad7f8dcf6..1b7cdc667 100644 --- a/MyBox/src/main/java/mara/mybox/tools/SoundTools.java +++ b/MyBox/src/main/java/mara/mybox/tools/SoundTools.java @@ -18,7 +18,7 @@ import javax.sound.sampled.Port; import javax.sound.sampled.SourceDataLine; import javazoom.jl.player.Player; -import static mara.mybox.objects.AppVaribles.logger; +import static mara.mybox.value.AppVaribles.logger; /** diff --git a/MyBox/src/main/java/mara/mybox/tools/SystemTools.java b/MyBox/src/main/java/mara/mybox/tools/SystemTools.java index 2759d5c9a..e66f97490 100644 --- a/MyBox/src/main/java/mara/mybox/tools/SystemTools.java +++ b/MyBox/src/main/java/mara/mybox/tools/SystemTools.java @@ -1,7 +1,11 @@ package mara.mybox.tools; +import java.awt.MouseInfo; +import java.awt.Point; import java.util.Map; -import static mara.mybox.objects.AppVaribles.logger; +import javafx.scene.image.Image; +import javafx.scene.input.Clipboard; +import static mara.mybox.value.AppVaribles.logger; /** * @Author Mara @@ -34,4 +38,32 @@ public static void currentThread() { } } + public static Point getMousePoint() { + return MouseInfo.getPointerInfo().getLocation(); + } + + public static Image fetchImageInClipboard(boolean clear) { + Clipboard clipboard = Clipboard.getSystemClipboard(); + if (!clipboard.hasImage()) { + return null; + } + Image image = clipboard.getImage(); + if (clear) { + clipboard.clear(); + } + return image; + } + + public static String fetchTextInClipboard(boolean clear) { + Clipboard clipboard = Clipboard.getSystemClipboard(); + if (!clipboard.hasString()) { + return null; + } + String text = clipboard.getString(); + if (clear) { + clipboard.clear(); + } + return text; + } + } diff --git a/MyBox/src/main/java/mara/mybox/tools/TextTools.java b/MyBox/src/main/java/mara/mybox/tools/TextTools.java index c4dc119cd..5ca1280b2 100644 --- a/MyBox/src/main/java/mara/mybox/tools/TextTools.java +++ b/MyBox/src/main/java/mara/mybox/tools/TextTools.java @@ -11,9 +11,9 @@ import java.util.List; import java.util.Map; import javafx.scene.control.IndexRange; -import mara.mybox.objects.FileEditInformation; -import static mara.mybox.objects.AppVaribles.logger; -import mara.mybox.objects.FileEditInformation.Line_Break; +import mara.mybox.data.FileEditInformation; +import static mara.mybox.value.AppVaribles.logger; +import mara.mybox.data.FileEditInformation.Line_Break; import thridparty.EncodingDetect; diff --git a/MyBox/src/main/java/mara/mybox/tools/ValueTools.java b/MyBox/src/main/java/mara/mybox/tools/ValueTools.java index 9bd1f3751..e3fcf385a 100644 --- a/MyBox/src/main/java/mara/mybox/tools/ValueTools.java +++ b/MyBox/src/main/java/mara/mybox/tools/ValueTools.java @@ -1,10 +1,12 @@ package mara.mybox.tools; import java.text.DecimalFormat; +import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Random; +import javafx.scene.control.IndexRange; /** * @Author Mara @@ -19,7 +21,7 @@ public static int getRandomInt(int max) { return r.nextInt(max); } - public static String fillNumber(int value, int digit) { + public static String fillLeftZero(int value, int digit) { String v = value + ""; for (int i = v.length(); i < digit; i++) { v = "0" + v; @@ -27,6 +29,14 @@ public static String fillNumber(int value, int digit) { return v; } + public static String fillRightZero(int value, int digit) { + String v = value + ""; + for (int i = v.length(); i < digit; i++) { + v += "0"; + } + return v; + } + public static String fillRightBlank(int value, int digit) { String v = value + ""; for (int i = v.length(); i < digit; i++) { @@ -49,31 +59,35 @@ public static String formatData(long data) { } public static float roundFloat2(float fvalue) { - return (float) Math.round(fvalue * 100.0) / 100.0f; + return (float) (Math.round(fvalue * 100)) / 100; } public static float roundFloat3(float fvalue) { - return (float) Math.round(fvalue * 1000.0) / 1000.0f; + return (float) Math.round(fvalue * 1000) / 1000; + } + + public static float roundFloat4(float fvalue) { + return (float) Math.round(fvalue * 10000) / 10000; } public static float roundFloat5(float fvalue) { - return (float) Math.round(fvalue * 100000.0) / 100000.0f; + return (float) Math.round(fvalue * 100000) / 100000; } public static double roundDouble3(double invalue) { - return (double) Math.round(invalue * 1000.0) / 1000.0; + return (double) Math.round(invalue * 1000) / 1000; } public static double roundDouble2(double invalue) { - return (double) Math.round(invalue * 100.0) / 100.0; + return (double) Math.round(invalue * 100) / 100; } public static double roundDouble4(double invalue) { - return (double) Math.round(invalue * 10000.0) / 10000.0; + return (double) Math.round(invalue * 10000) / 10000; } public static double roundDouble5(double invalue) { - return (double) Math.round(invalue * 100000.0) / 100000.0; + return (double) Math.round(invalue * 100000) / 100000; } public static float[] matrix2Array(float[][] m) { @@ -117,17 +131,6 @@ public static long getAvaliableMemoryMB() { return getAvaliableMemory() / (1024 * 1024); } -// public static List sortList(List numbers) { -// List sorted = new ArrayList<>(); -// sorted.addAll(numbers); -// Collections.sort(sorted, new Comparator() { -// @Override -// public int compare(Integer p1, Integer p2) { -// return p1 - p2; -// } -// }); -// return sorted; -// } public static void sortList(List numbers) { Collections.sort(numbers, new Comparator() { @Override @@ -137,4 +140,31 @@ public int compare(Integer p1, Integer p2) { }); } + public static void sortArray(int[] numbers) { + List list = new ArrayList<>(); + for (int i : numbers) { + list.add(i); + } + Collections.sort(list, new Comparator() { + @Override + public int compare(Integer p1, Integer p2) { + return p1 - p2; + } + }); + } + + public static int mapInt(int value, IndexRange originalRange, IndexRange newlRange) { + if (originalRange == null || newlRange == null + || originalRange.getStart() > value || originalRange.getEnd() < value) { + return value; + } + int len = value - originalRange.getStart() + 1; + double ratio = newlRange.getLength() * 1.0 / originalRange.getLength(); + return newlRange.getStart() + (int) Math.round(len * ratio); + } + + public static int zipInt(int value, int zipStep) { + return (int) (Math.round((value + zipStep / 2) / zipStep)) * zipStep; + } + } diff --git a/MyBox/src/main/java/mara/mybox/objects/AppVaribles.java b/MyBox/src/main/java/mara/mybox/value/AppVaribles.java similarity index 88% rename from MyBox/src/main/java/mara/mybox/objects/AppVaribles.java rename to MyBox/src/main/java/mara/mybox/value/AppVaribles.java index 31be41673..7afab2230 100644 --- a/MyBox/src/main/java/mara/mybox/objects/AppVaribles.java +++ b/MyBox/src/main/java/mara/mybox/value/AppVaribles.java @@ -1,5 +1,6 @@ -package mara.mybox.objects; +package mara.mybox.value; +import mara.mybox.value.CommonValues; import java.io.File; import java.util.HashMap; import java.util.Locale; @@ -10,11 +11,11 @@ import mara.mybox.controller.AlarmClockController; import mara.mybox.db.TableSystemConf; import mara.mybox.db.TableUserConf; -import static mara.mybox.objects.CommonValues.BundleEnUS; -import static mara.mybox.objects.CommonValues.BundleEsES; -import static mara.mybox.objects.CommonValues.BundleFrFR; -import static mara.mybox.objects.CommonValues.BundleRuRU; -import static mara.mybox.objects.CommonValues.BundleZhCN; +import static mara.mybox.value.CommonValues.BundleEnUS; +import static mara.mybox.value.CommonValues.BundleEsES; +import static mara.mybox.value.CommonValues.BundleFrFR; +import static mara.mybox.value.CommonValues.BundleRuRU; +import static mara.mybox.value.CommonValues.BundleZhCN; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -36,6 +37,7 @@ public class AppVaribles { public static Map> scheduledTasks; public static AlarmClockController alarmClockController; public static MemoryUsageSetting PdfMemUsage; + public static int PaneFontSize; public AppVaribles() { } @@ -152,20 +154,13 @@ public static String getStyle() { return getUserConfigValue("InterfaceStyle", CommonValues.DefaultStyle); } - public static String getTempPath() { - return getUserConfigValue("TempDir", CommonValues.UserFilePath); - } - - public static File getTempPathFile() { - File tempdir = new File(AppVaribles.getTempPath()); - if (!tempdir.exists()) { - tempdir.mkdirs(); - } - return tempdir; + public static File getUserTempPath() { + return AppVaribles.getUserConfigPath(CommonValues.userTempPathKey); } public static String getImageHisPath() { - String imageHistoriesPath = AppVaribles.getTempPath() + File.separator + "imageHistories"; + String imageHistoriesPath = AppVaribles.getUserTempPath().getAbsolutePath() + + File.separator + "imageHistories"; File path = new File(imageHistoriesPath); if (!path.exists()) { path.mkdirs(); @@ -177,6 +172,14 @@ public static int getCommentsDelay() { return getUserConfigInt("CommentsDelay", 3000); } + public static int getPaneFontSize() { + return getUserConfigInt("PaneFontSize", 15); + } + + public static void setPaneFontSize(int size) { + setUserConfigInt("PaneFontSize", size); + } + public static boolean isShowComments() { return AppVaribles.getUserConfigBoolean("ShowComments", true); } @@ -238,21 +241,28 @@ public static boolean getUserConfigBoolean(String key) { return AppVaribles.getUserConfigBoolean(key, true); } - public static String getUserConfigPath(String key, String defaultValue) { + public static File getUserConfigPath(String key) { + return getUserConfigPath(key, CommonValues.AppDataRoot); + } + + public static File getUserConfigPath(String key, String defaultValue) { try { // logger.debug("getUserConfigValue:" + key); - String path; + String pathString; if (userConfigValues.containsKey(key)) { - path = userConfigValues.get(key); + pathString = userConfigValues.get(key); } else { - path = TableUserConf.read(key, defaultValue); + pathString = TableUserConf.read(key, defaultValue); } - File file = new File(path); - if (!file.exists() || !file.isDirectory()) { + File path = new File(pathString); + if (!path.exists() || !path.isDirectory()) { deleteUserConfigValue(key); - path = CommonValues.UserFilePath; + path = new File(CommonValues.AppDataRoot); + if (!path.exists()) { + path.mkdirs(); + } } - userConfigValues.put(key, path); + userConfigValues.put(key, path.getAbsolutePath()); return path; } catch (Exception e) { logger.error(e.toString()); diff --git a/MyBox/src/main/java/mara/mybox/objects/CommonValues.java b/MyBox/src/main/java/mara/mybox/value/CommonValues.java similarity index 92% rename from MyBox/src/main/java/mara/mybox/objects/CommonValues.java rename to MyBox/src/main/java/mara/mybox/value/CommonValues.java index 09cf2edf9..36a396a6b 100644 --- a/MyBox/src/main/java/mara/mybox/objects/CommonValues.java +++ b/MyBox/src/main/java/mara/mybox/value/CommonValues.java @@ -1,4 +1,4 @@ -package mara.mybox.objects; +package mara.mybox.value; import java.awt.Color; import java.io.File; @@ -18,14 +18,23 @@ */ public class CommonValues { - public static final String AppVersion = "4.8"; - public static final String AppVersionDate = "2019-01-29"; + public static final String AppVersion = "4.9"; + public static final String AppVersionDate = "2019-02-04"; - public static final String UserFilePath = System.getProperty("user.home") + File.separator + "mybox"; - public static final String TempPath = UserFilePath + File.separator + "temp"; - public static final String UserConfigFile = UserFilePath + File.separator + ".conf.properties"; - public static final String AlarmClocksFile = UserFilePath + File.separator + ".alarmClocks"; - public static final String DerbyDB = UserFilePath + File.separator + "mybox_derby"; + public static final String AppDataRoot = System.getProperty("user.home") + File.separator + "mybox"; + public static final File AppTempPath = new File(AppDataRoot + File.separator + "AppTemp"); + public static final File AppDerbyPath = new File(AppDataRoot + File.separator + "mybox_derby"); + public static List AppDataPaths = new ArrayList() { + { + add(AppTempPath); + add(AppDerbyPath); + } + }; + + public static final String UserConfigFile = AppDataRoot + File.separator + ".conf.properties"; + public static final String AlarmClocksFile = AppDataRoot + File.separator + ".alarmClocks"; + + public static final String userTempPathKey = "TempDir"; public static final Image AppIcon = new Image("img/mybox.png"); public static final String MyBoxStyle = "/styles/MyBox.css"; @@ -61,7 +70,7 @@ public class CommonValues { public static final String ImageInformationFxml = "/fxml/ImageInformation.fxml"; public static final String ImageViewerFxml = "/fxml/ImageViewer.fxml"; public static final String ImageViewerIFxml = "/fxml/ImageViewerI.fxml"; - public static final String ImagesViewerFxml = "/fxml/ImagesViewer.fxml"; + public static final String ImagesBrowserFxml = "/fxml/ImagesBrowser.fxml"; public static final String ImageConverterFxml = "/fxml/ImageConverter.fxml"; public static final String ImageConverterBatchFxml = "/fxml/ImageConverterBatch.fxml"; public static final String ImageManufactureFileFxml = "/fxml/ImageManufactureFile.fxml"; @@ -69,7 +78,6 @@ public class CommonValues { public static final String ImageManufactureCropFxml = "/fxml/ImageManufactureCrop.fxml"; public static final String ImageManufactureColorFxml = "/fxml/ImageManufactureColor.fxml"; public static final String ImageManufactureEffectsFxml = "/fxml/ImageManufactureEffects.fxml"; - public static final String ImageManufactureConvolutionFxml = "/fxml/ImageManufactureConvolution.fxml"; public static final String ImageManufactureTextFxml = "/fxml/ImageManufactureText.fxml"; public static final String ImageManufactureCoverFxml = "/fxml/ImageManufactureCover.fxml"; public static final String ImageManufactureArcFxml = "/fxml/ImageManufactureArc.fxml"; @@ -86,7 +94,6 @@ public class CommonValues { public static final String ImageManufactureBatchCropFxml = "/fxml/ImageManufactureBatchCrop.fxml"; public static final String ImageManufactureBatchColorFxml = "/fxml/ImageManufactureBatchColor.fxml"; public static final String ImageManufactureBatchEffectsFxml = "/fxml/ImageManufactureBatchEffects.fxml"; - public static final String ImageManufactureBatchConvolutionFxml = "/fxml/ImageManufactureBatchConvolution.fxml"; public static final String ImageManufactureBatchReplaceColorFxml = "/fxml/ImageManufactureBatchReplaceColor.fxml"; public static final String ImageManufactureBatchTextFxml = "/fxml/ImageManufactureBatchText.fxml"; public static final String ImageManufactureBatchArcFxml = "/fxml/ImageManufactureBatchArc.fxml"; @@ -103,6 +110,7 @@ public class CommonValues { public static final String ImageGifEditerFxml = "/fxml/ImageGifEditer.fxml"; public static final String ImageTiffEditerFxml = "/fxml/ImageTiffEditer.fxml"; public static final String ImageFramesViewerFxml = "/fxml/ImageFramesViewer.fxml"; + public static final String ImageStatisticFxml = "/fxml/ImageStatistic.fxml"; public static final String PixelsCalculatorFxml = "/fxml/PixelsCalculator.fxml"; public static final String ConvolutionKernelManagerFxml = "/fxml/ConvolutionKernelManager.fxml"; public static final String ColorPaletteFxml = "/fxml/ColorPalette.fxml"; @@ -122,7 +130,7 @@ public class CommonValues { public static final String FileFilterFxml = "/fxml/FileFilter.fxml"; public static final String FileCutFxml = "/fxml/FileCut.fxml"; public static final String FileMergeFxml = "/fxml/FileMerge.fxml"; - public static final String SnapScreenFxml = "/fxml/SnapScreen.fxml"; + public static final String RecordImagesInSystemClipboardFxml = "/fxml/RecordImagesInSystemClipboard.fxml"; public static final Locale LocaleZhCN = new Locale("zh", "CN"); public static final Locale LocaleEnUS = new Locale("en", "US"); diff --git a/MyBox/src/main/resources/bundles/Messages.properties b/MyBox/src/main/resources/bundles/Messages.properties index 6bbf15255..82899fb07 100644 --- a/MyBox/src/main/resources/bundles/Messages.properties +++ b/MyBox/src/main/resources/bundles/Messages.properties @@ -429,7 +429,7 @@ OK=OK PaneSize=Pane Size CurrentPixels=Current Pixels Tips=Tips -ImageManufactureTips=Image can be viewed, browsed, and manufactured in this function.\n\n"Zoom In", "Zoom Out", and movement buttons under tab "View" are to display the image but not to modify it.\nTo modify size, color, or figure of the image, use the functions under other tabs.\n\nClick "Save"(CTRL-s) button to write all modifications in the image file.\nClick "Recover"(CTRL-r) button can discard all of modifications and set back the original image.\n"Undo"(CTRL-z)/"Redo"(CTRL-y) buttons are to discard/return the last modification.\n"Histories"(CTRL-h) can help to reback to previous updates.\nShortcut "CTRL-c" is supported to copy current image in system clipboard.\n\nThe bottom label shows the base attributes of the image. The changed value of pixels will be shown too.\n\nSome image formats like jpg, bmp, and gif, do not support alpha channel, so function "Oacity" is disabled to these images. \n\nShort cuts are defined as following:\n"Image Size": CTRL+"1" "Pane Size": CTRL+"2" "Zoom In": CTRL+"3" "Zoom Out": CTRL+"4" \n"Save": CTRL+"s" "Recover": CTRL+"r" "Undo": CTRL+"z" "Redo": CTRL+"y" \n"Histories": CTRL+"h" "Copy": CTRL+"c" \n\nShow/Hide the comments: CTRL+"m" (Not include me) +ImageManufactureTips=Zoom and movement do not change the image itself.\nTo modify size, color, or figure of the image, use the functions under tabs.\n\nFormats like jpg/bmp/gif do not support alpha, so "Opacity"/"Transparent" is disabled to them. \n\nImage will be saved in 8bit RGB/ARGB format even when changed as gray or black-white.\nPlease use tool "Convert Image" to compress image file.\n\nShortcuts in this stage:\n"CTRL+z" Undo: Discard last modification.\n"CTRL+y" Redo: Return to last modification.\n"CTRL+r" Discard all of modifications and recover to original image.\n"CTRL+c" Copy the image or its cropped area to system clipboard.\n"CTRL+s"\t Save modifications of the image.\n"CTRL+g"\t OK(If any).\n"CTRL+i" Display the image information.\n"CTRL+h" Display the modification Histories list.\n"CTRL+1" Zoom the image as its original size. \n"CTRL+2" Zoom the image as the pane's size. \n"CTRL+3" Zoom in the image a little. \n"CTRL+4" Zoom out the image a little. \n"CTRL+p" Pop a new window to display current image. \n"CTRL+f" Make current image as reference image. \n"CTRL+q" Set color value against current image. (Under Color tab) \n"CTRL+w" Increase color value against current image. (Under Color tab) \n"CTRL+e" Decrease color value against current image. (Under Color tab) \n"PAGE DOWN" Next image in same directory. (Under Browse tab) \n"PAGE UP" Previous image in same directory. (Under Browse tab) \n"CTRL+m" Show/Hide the comments(Not affect tips). \n"CTRL+-" Decrease font size. \n"CTRL+=" Increase font size. \n"F5" Close the stage.\n ColorPalette=Color Palette Hexadecimal=Hexadecimal Green=Green @@ -512,7 +512,7 @@ Scope...=Scope... Set=Set Scope=Scope Value=Value -ColorMatchComments=How to match colors: \n1) "Color Distance" indicates the difference between 2 colors.\n "Color difference" can be referred in "https://en.wikipedia.org/wiki/Color_difference" \n2) When the distance is less than the defined distance value, it means the 2 colors are "Matched". \n3) When the distance is defined as zero, it means color must be matched accurately.\n4) Multiple colors can be selected to compare with pixels in the image. \n Their relationship is "OR", which means pixel' color can compare with any of selected color. \n\nShortcut "CTRL-m" to show/hide the comments. +ColorMatchComments=How to match colors: \n1) "Color Distance" indicates the difference between 2 colors.\n "Color difference" can be referred in "https://en.wikipedia.org/wiki/Color_difference" \n2) When the distance is less than the defined distance value, it means the 2 colors are "Matched". \n3) When the distance is defined as zero, it means color must be matched accurately.\n4) Multiple colors can be selected to compare with pixels in the image. \n Their relationship is "OR", which means pixel' color can compare with any of selected color. \n\nShortcut "CTRL+m" to show/hide the comments. ContinueClickColor=Click different pixel to pick more color. InvalidRectangle=Invalid Area. Left-Top should be smaller than Right-Bottom. LineColor=Line Color @@ -646,7 +646,7 @@ SplitPdf=Split Pdf File PagesNumberOfEachFile=Pages Number of Each file NumberOfFilesDividedEqually=Number of Files by Dividing Equally StartEndList=Start-End List -StartEndComments=List of "StartNumber-EndNumber" separated by comma, like "1-4,67-83, 15-29". From 1. +StartEndComments=List of "StartNumber-EndNumber" separated by comma, like "1-4,67-83, 15-29". 1-Based. WrongStartEnd=Following "Start-End" are invalid: FilesGeneratedUnder=Following files are generated under NetworkTools=Network Tools @@ -689,7 +689,7 @@ WeiboEarlestMonth=Weibo started from 2009-08 MergePdfMonth=Merge PDF of Month WebPageScale=Web Page Zoom Scale WebWidth=Web Page Width -WowAsExample=Weibo of Wow As Example +WowAsExample=Wow As Example ScreenWidth=Screen Width PageWidth=Page Width A4Landscape=A4 Landscape @@ -868,7 +868,7 @@ ImageManufactureBatchEffects=Manufacture Image - Batch - Effects Posterizing=Posterizing SmallValue=Small Value BigValue=Big Value -ThresholdingComments=The color components of the destination image will contain either the small value or the big value.\nFor example, when the small value is 0 and the big value 255, after processed, the red, green, and blue values of the pixels will be either 0 or 255. \nThus, the processed image can only contain the following colors:\n black (red = 0, green = 0, blue = 0)\n white (red = 255, green = 255, blue = 255)\n red (red = 255, green = 0, blue = 0)\n green (red = 0, green = 255, blue = 0)\n blue (red = 0, green = 0, blue = 255)\n yellow (red = 255, green = 255, blue = 0)\n magenta (red = 255, green = 0, blue = 255)\n cyan (red = 0, green = 255, blue = 255)\n\nYou can use menu "Settings" to show/hide the comments. +ThresholdingComments=The color components of the destination image will contain either the small value or the big value.\nFor example, when the small value is 0 and the big value 255, after processed, \nthe red, green, and blue values of the pixels will be either 0 or 255. \nThus, the processed image can only contain the following colors:\n black (red = 0, green = 0, blue = 0)\n white (red = 255, green = 255, blue = 255)\n red (red = 255, green = 0, blue = 0)\n green (red = 0, green = 255, blue = 0)\n blue (red = 0, green = 0, blue = 255)\n yellow (red = 255, green = 255, blue = 0)\n magenta (red = 255, green = 0, blue = 255)\n cyan (red = 0, green = 255, blue = 255)\n\nYou can use menu "Settings" to show/hide the comments. WeiboAddressComments2=By clicking the account's "Main page", its address will be shown in browser's address input.\nNotice, nick address is NOT true address. Example "\u535a\u7269\u6742\u5fd7" has its nick address "https://weibo.com/bowu"\nbut its valid address is actual "https://weibo.com/p/1002061195054531".\n\nYou can use menu "Settings" to show/hide the comments. SaveCtrl=Save(Ctrl-s) InterfaceStyle=Interface Style @@ -1033,7 +1033,7 @@ ViewAfterSave=View After Save KeepImagesSize=Keep Images Size AllSetAs=All Set As Index=Index -ViewGifComments=This tool ignores "interval" and "loop" defined by the image itself +GifViewTips=This tool ignores "interval" and "loop" defined by the image itself.\n\nShortcuts in this stage\n"CTRL+i" Display the image information.\n"PAGE DOWN" Next frame in this file. \n"PAGE UP" Previous frame in this file. \n"CTRL+1" Zoom the image as its original size. \n"CTRL+2" Zoom the image as the pane's size. \n"CTRL+3" Zoom in the image a little. \n"CTRL+4" Zoom out the image a little. \n"CTRL+m" Show/Hide the comments(Not affect tips). \n"CTRL+-" Decrease font size. \n"CTRL+=" Increase font size. \n"F5" Close the stage. Operation=Operation OpenPathDot=Open Path... Area=Area @@ -1203,7 +1203,6 @@ IncludeAll=Include All NotIncludeAll=Not Include All LineNumber=Line Number DisplayHexadecimalByCurrent=Display Hexadecimal By Current Charset -PaginateComments=When page is changed, part functions are unavaliable before saved EncodeComments=When BOM is detected in file, file charset is definiate FilterTypesComments=Include One : a | b | c\nInclude All: a & b & c\nNot Include Any: !( a | b | c) = !a & !b & !c\nNot Include All : !(a & b & c) = !a | !b | !c TextLineBreakComments=Please filter files to avoid handle line break for binary files that is nonsense. @@ -1219,7 +1218,6 @@ BytesNumber=Bytes Number DetectLineBreak=Detect Line Break Character=Character BytesHex=Bytes(Hexadecimal) -ByteHexComments=Each byte is expressed as 2 characters of hexadecimal, like 05, A1, EF. All spaces, line breaks, and invalid values will be ignored InvalidData=Invalid Data ChangeAsWhenSave=Change As(Take effect when save) LFHex=LF(0A) @@ -1229,15 +1227,13 @@ SeparateByCommaBlanksInvolved=Separate By Comma. Blanks are involved to compare. Count=Count CountNumber=Found {0} matched subStrings. NotSupportFrameSet=Not Support FrameSet -OnlyForDisplayNoEffect=Only for display. No actual effect. -DecodeComments=Charset, line break, and pagination may affect decoding FileCut=Cut File SplitByFilesNumber=Split By Files Number SplitByBytesNumber=Split By Bytes Number CutByStartEndByteList=Cut By "StartByte-EndByte" List -StartEndByteComments=List of "StartByte-EndByte" separated by comma, like "1-4000,67KB-83KB, 15mb-29mb ". From 1. +StartEndByteComments=List of "StartByte-EndByte" separated by comma, like "1-4000,67K-83K, 15m-29m ". 1-Based. FilesGenerated={0} files generated -BytesValuesComments=Valid values like: 5000, 20kb, 60MB, 1GB. +AbbrevValuesComments=Valid values like: 5000, 20k, 60M, 1G. FileMerge=Merge File SnapScreen=Snap Screen Selection=Selection @@ -1247,3 +1243,95 @@ Byte=Byte PdfView=View PDF - Image Mode Select=Select TransparentBackground=Transparent Background +ConfirmWhenDelete=Confirm When Delete +ViewRecordedImages=View Recorded Images +SaveRecordedImages=Save recorded images +SaveOptions=Save Options +StartRecording=Start Recording +ActiveWindow=Active Window +StopRecording=Stop Recording +ImageViewerTips=When "Crop" is selected\uff0c "Copy" and "Save As" are for the selected area.\nTo select area, left click the image to set the Left-Top and right click to set Right-Bottom.\n\nWhen "Crop" is not selected, "Copy" and "Save As" are for whole image.\n\nShortcuts in this stage\n"CTRL+c" Copy the image or its cropped area to system clipboard.\n"CTRL+s"\t Save the image or its cropped area as an image file.\n"CTRL+d / DELETE" Delete the image file.\n"CTRL+i" Display the image information.\n"CTRL+a" Select all of the image.\n"PAGE DOWN" Next image in same directory. \n"PAGE UP" Previous image in same directory. \n"CTRL+1" Zoom the image as its original size. \n"CTRL+2" Zoom the image as the pane's size. \n"CTRL+3" Zoom in the image a little. \n"CTRL+4" Zoom out the image a little. \n"CTRL+m" Show/Hide the comments(Not affect tips). \n"CTRL+-" Decrease font size. \n"CTRL+=" Increase font size. \n"F5" Close the stage. +RecordingImages={0} images have been recorded. Waiting for new images... +RecordImagesTips=When "Start" is clicked, the tool will monitor images in system clipboard and save/display them.\n\nImages in system clipboard come from screenshots or pictures generated from softwares like operation "CTRL+c".\n\nOn Windows, shortcuts to make screenshots:\n"PrintScreen" Make snapshot of full screen.\n"Alt+PrintScreen" Make snapshot of current active window.\n\nOn Linux, shortcuts to make screenshots:\n"Ctrl+PrintScreen" Make snapshot of full screen.\n"Ctrl+Alt+PrintScreen" Make snapshot of current active window.\n"Shift+Ctrl+PrintScreen" Make snapshot of selected area.\n\nOn Mac, shortcuts to make screenshots:\n"Command+Control+Shift+3" Make snapshot of full screen.\n"Command+Control+Shift+4" Make snapshot of selected area.\n"Command+Control+Shift+4+Spacebar" Make snapshot of current active window.\n +RecordImagesInSystemClipBoard=Record Images In System Clipboard +DirectoryReserved=This is reserved directory of MyBox. +ImagesBrowser=Browse Images +Manufacture=Manufacture +PdfViewTips=When "Crop" is selected, "Copy" and "Save As" are for the selected area.\nTo select area, left click the image to set the Left-Top and right click to set Right-Bottom.\n\nWhen "Crop" is not selected, "Copy" and "Save As" are for whole image.\n\nShortcuts in this stage:\n"CTRL+i" Display the file information.\n"CTRL+c" Copy the image or its cropped area to system clipboard.\n"CTRL+s"\t Save the image or its cropped area as an image file.\n"CTRL+a" Select all of the image.\n"PAGE DOWN" Next page of this file. \n"PAGE UP" Previous page of this file. \n"HOME" First page of this file. \n"END" Last page of this file. \n"CTRL+1" Zoom the image as its original size. \n"CTRL+2" Zoom the image as the pane's size. \n"CTRL+3" Zoom in the image a little. \n"CTRL+4" Zoom out the image a little. \n"CTRL+m" Show/Hide the comments(Not affect tips). \n"CTRL+-" Decrease font size. \n"CTRL+=" Increase font size. \n"F5" Close the stage. +ImageBrowserTips=Click an image to select it, and click it again to unselect it.\nDouble click an image to view it in new stage.\n\nWhen images are selected, zoom/rotation/movement/deletion are for the selected images.\nWhen only one image is selected, View/Rename/Information works.\nWhen no image is selected, zoom/rotation/movement are for all images in this stage.\n\nShortcuts in this stage\n"CTRL+1" Zoom images as their original size. \n"CTRL+2" Zoom images as their pane's size. \n"CTRL+3" Zoom in images a little. \n"CTRL+4" Zoom out images a little. \n"CTRL+i" Display selected image's information.\n"CTRL+d / DELETE" Delete selected image files.\n"PAGE DOWN" Next batch of images in same directory. \n"PAGE UP" Previous batch of images in same directory. \n"CTRL+m" Show/Hide the comments(Not affect tips). \n"CTRL+-" Decrease font size. \n"CTRL+=" Increase font size. \n"F5" Close the stage. +BytesEditerTips=All spaces, line breaks, and invalid values will be ignored\u3002\nLine breaks are only for displaying and do not effect bytes values.\n\nWhen "Decode" under Text tab is checked, bytes are decoded with the selected character set.\nBytes' decoding is affected by charset, line break, and pagination.\nThe decoded texts are shown in the right pane, and can be scrolled synchronously with the bytes of left pane.\nWhen some bytes are selected in left, corresponding decoded texts are highlighted in right.\n\nWhen bytes in page are modified, part functions are unavaliable before changes are saved.\n\nShortcuts in this stage\n"CTRL+c" Copy selected bytes to system clipboard.\n"CTRL+v" Paste strings of system clipboard.\n"CTRL+x" Cut selected bytes and copy to system clipboard.\n"CTRL+d / DELETE" Delete selected bytes.\n"CTRL+a" Select all of bytes in this page.\n"CTRL+s"\t Save modifications.\n"CTRL+z" Undo last modification.\n"CTRL+y" Redo last modification.\n"CTRL+r" Discard unsaved modifications and recover to original page.\n"CTRL+f"\t Find first. (Under Find/Replace tab)\n"CTRL+l" Find last. (Under Find/Replace tab)\n"CTRL+n" Find next. (Under Find/Replace tab)\n"CTRL+p" Find previous. (Under Find/Replace tab)\n"CTRL+e" Replace. (Under Find/Replace tab)\n"PAGE DOWN" Next page of this file. \n"PAGE UP" Previous page of this file. \n"HOME" First page of this file. \n"END" Last page of this file. \n"CTRL+m" Show/Hide the comments(Not affect tips). \n"CTRL+-" Decrease font size. \n"CTRL+=" Increase font size. \n"F5" Close the stage. +TextEditerTips=Character Set and Line Break can be changed and take effect when file is saved. \n\nWhen "Display Hexadecimal" under Bytes tab is checked, texts are encoded with current character set.\nThe encoded bytes are shown in the right pane, and can be scrolled synchronously with the texts of left pane.\nWhen some texts are selected in left, corresponding encoded bytes are highlighted in right.\n\nWhen texts in page are modified, part functions are unavaliable before changes are saved.\n\nShortcuts in this stage\n"CTRL+c" Copy selected texts to system clipboard.\n"CTRL+v" Paste strings of system clipboard.\n"CTRL+x" Cut selected texts and copy to system clipboard.\n"CTRL+d / DELETE" Delete selected texts.\n"CTRL+a" Select all of texts in this page.\n"CTRL+s"\t Save modifications.\n"CTRL+z" Undo last modification.\n"CTRL+y" Redo last modification.\n"CTRL+r" Discard unsaved modifications and recover to original page.\n"CTRL+f"\t Find first. (Under Find/Replace tab)\n"CTRL+l" Find last. (Under Find/Replace tab)\n"CTRL+n" Find next. (Under Find/Replace tab)\n"CTRL+p" Find previous. (Under Find/Replace tab)\n"CTRL+e" Replace. (Under Find/Replace tab)\n"PAGE DOWN" Next page of this file. \n"PAGE UP" Previous page of this file. \n"HOME" First page of this file. \n"END" Last page of this file. \n"CTRL+m" Show/Hide the comments(Not affect tips). \n"CTRL+-" Decrease font size. \n"CTRL+=" Increase font size. \n"F5" Close the stage. +WhenNewImageInSystemBoard=When new image appears in system board +SaveAndView=Save And View +RecordOptions=Record Options +ImageCalculation=Calculate Image +GreyHistogram=Grey Histogram +RedHistogram=Red Histogram +GreenHistogram=Green Histogram +BlueHistogram=Blue Histogram +OpacityHistogram=Opacity Histogram +HueHistogram=Hue Histogram +SaturationHistogram=Saturation Histogram +BrightnessHistogram=Brightness Histogram +Histogram=Histogram +Data=Data +PixelsNumber=Pixels Number +DataType=Data Type +Greyscale=Greyscale +GreyValue=Grey Value +ImageStatistic=Image Statistic +StatisticValue=Statistic Value +OccurrenceNumber=Occurrence Number +Median=Median +Statistic=Statistic +Percentage=Percentage +Sum=Sum +Showcase=Showcase +Sequence=Sequence +OrderSequence=Order Sequence +HueGrades=Hue Grades +BrightnessGrades=Brightness Grades +SaturationGrades=Saturation Grades +DataNumber=Data Number +Algorithm=Algorithm +Palette=Palette +Division=Division +Mod=Mod +MedianCut=Median Cut +kMeansClustering=k-Means Clustering +ColorsNumber=Colors Number +RGBUniformQuantization=RGB Uniform Quantization +HSBUniformQuantization=HSB Uniform Quantization +ColorHistogram=Color Histogram +ColorPie=Color Pie +ColorQuantization=Color Quantization +Mode=Mode +CategoryNumber=Category Number +Dithering=Dithering +QuantizationComments=Technique of reducing distinct colors in image is called "Color Quantization".\n"Dithering" is to optimzie the result of Color Quantization. It only works for whole image.\n +Variance=Variance +Skewness=Skewness +Mean=Mean +ColorFeatures=Color Features +BWThresholdComments=Threshold should be between 0 and 255, and can be empty to use default value. \nDithering only works for whole image. +Pop=Pop +Ref=Ref +BOMcomments=BOM(Byte Order Marks) is 2 or 3 bytes in head of the file for UTF-16 or UTF-32.\nSome UTF-8 files have BOM written by some Windows programs which can confuse other platforms. \n\n +FontSize12=Font Size 12px +FontSize15=Font Size 15px +FontSize17=Font Size 17px +DitherComments=Dithering is a technique to diffuse quantization error to avoid color banding.\nIt may improve image quality after color quantization(Reduce colors in palette). +Contrast=Contrast +HistogramEqualization=Histogram Equalization +SampleSize=Sample Size +HSBHistogramEqualization=HSB Histogram Equalization +GrayHistogramEqualization=Gray Histogram Equalization +AdaptiveHistogramEqualization=Adaptive Histogram Equalization +GrayHistogramShifting=Gray Histogram Shifting +Offset=Offset +LumaHistogramEqualization=Luma Histogram Equalization +GrayHistogramStretching=Gray Histogram Stretching +LeftThreshold=Left Threshold +RightThreshold=Right Threshold +ColorMoments=Color Moments +Grey=Grey diff --git a/MyBox/src/main/resources/bundles/Messages_en_US.properties b/MyBox/src/main/resources/bundles/Messages_en_US.properties index 74f86ce8f..70c92e177 100644 --- a/MyBox/src/main/resources/bundles/Messages_en_US.properties +++ b/MyBox/src/main/resources/bundles/Messages_en_US.properties @@ -429,7 +429,7 @@ OK=OK PaneSize=Pane Size CurrentPixels=Current Pixels Tips=Tips -ImageManufactureTips=Image can be viewed, browsed, and manufactured in this function.\n\n"Zoom In", "Zoom Out", and movement buttons under tab "View" are to display the image but not to modify it.\nTo modify size, color, or figure of the image, use the functions under other tabs.\n\nClick "Save"(CTRL-s) button to write all modifications in the image file.\nClick "Recover"(CTRL-r) button can discard all of modifications and set back the original image.\n"Undo"(CTRL-z)/"Redo"(CTRL-y) buttons are to discard/return the last modification.\n"Histories"(CTRL-h) can help to reback to previous updates.\nShortcut "CTRL-c" is supported to copy current image in system clipboard.\n\nThe bottom label shows the base attributes of the image. The changed value of pixels will be shown too.\n\nSome image formats like jpg, bmp, and gif, do not support alpha channel, so function "Oacity" is disabled to these images. \n\nShort cuts are defined as following:\n"Image Size": CTRL+"1" "Pane Size": CTRL+"2" "Zoom In": CTRL+"3" "Zoom Out": CTRL+"4" \n"Save": CTRL+"s" "Recover": CTRL+"r" "Undo": CTRL+"z" "Redo": CTRL+"y" \n"Histories": CTRL+"h" "Copy": CTRL+"c" \n\nShow/Hide the comments: CTRL+"m" (Not include me) +ImageManufactureTips=Zoom and movement do not change the image itself.\nTo modify size, color, or figure of the image, use the functions under tabs.\n\nFormats like jpg/bmp/gif do not support alpha, so "Opacity"/"Transparent" is disabled to them. \n\nImage will be saved in 8bit RGB/ARGB format even when changed as gray or black-white.\nPlease use tool "Convert Image" to compress image file.\n\nShortcuts in this stage:\n"CTRL+z" Undo: Discard last modification.\n"CTRL+y" Redo: Return to last modification.\n"CTRL+r" Discard all of modifications and recover to original image.\n"CTRL+c" Copy the image or its cropped area to system clipboard.\n"CTRL+s"\t Save modifications of the image.\n"CTRL+g"\t OK(If any).\n"CTRL+i" Display the image information.\n"CTRL+h" Display the modification Histories list.\n"CTRL+1" Zoom the image as its original size. \n"CTRL+2" Zoom the image as the pane's size. \n"CTRL+3" Zoom in the image a little. \n"CTRL+4" Zoom out the image a little. \n"CTRL+p" Pop a new window to display current image. \n"CTRL+f" Make current image as reference image. \n"CTRL+q" Set color value against current image. (Under Color tab) \n"CTRL+w" Increase color value against current image. (Under Color tab) \n"CTRL+e" Decrease color value against current image. (Under Color tab) \n"PAGE DOWN" Next image in same directory. (Under Browse tab) \n"PAGE UP" Previous image in same directory. (Under Browse tab) \n"CTRL+m" Show/Hide the comments(Not affect tips). \n"CTRL+-" Decrease font size. \n"CTRL+=" Increase font size. \n"F5" Close the stage.\n ColorPalette=Color Palette Hexadecimal=Hexadecimal Green=Green @@ -512,7 +512,7 @@ Scope...=Scope... Set=Set Scope=Scope Value=Value -ColorMatchComments=How to match colors: \n1) "Color Distance" indicates the difference between 2 colors.\n "Color difference" can be referred in "https://en.wikipedia.org/wiki/Color_difference" \n2) When the distance is less than the defined distance value, it means the 2 colors are "Matched". \n3) When the distance is defined as zero, it means color must be matched accurately.\n4) Multiple colors can be selected to compare with pixels in the image. \n Their relationship is "OR", which means pixel' color can compare with any of selected color. \n\nShortcut "CTRL-m" to show/hide the comments. +ColorMatchComments=How to match colors: \n1) "Color Distance" indicates the difference between 2 colors.\n "Color difference" can be referred in "https://en.wikipedia.org/wiki/Color_difference" \n2) When the distance is less than the defined distance value, it means the 2 colors are "Matched". \n3) When the distance is defined as zero, it means color must be matched accurately.\n4) Multiple colors can be selected to compare with pixels in the image. \n Their relationship is "OR", which means pixel' color can compare with any of selected color. \n\nShortcut "CTRL+m" to show/hide the comments. ContinueClickColor=Click different pixel to pick more color. InvalidRectangle=Invalid Area. Left-Top should be smaller than Right-Bottom. LineColor=Line Color @@ -646,7 +646,7 @@ SplitPdf=Split Pdf File PagesNumberOfEachFile=Pages Number of Each file NumberOfFilesDividedEqually=Number of Files by Dividing Equally StartEndList=Start-End List -StartEndComments=List of "StartNumber-EndNumber" separated by comma, like "1-4,67-83, 15-29 ". From 1. +StartEndComments=List of "StartNumber-EndNumber" separated by comma, like "1-4,67-83, 15-29". 1-Based. WrongStartEnd=Following "Start-End" are invalid: FilesGeneratedUnder=Following files are generated under NetworkTools=Network Tools @@ -689,7 +689,7 @@ WeiboEarlestMonth=Weibo started from 2009-08 MergePdfMonth=Merge PDF of Month WebPageScale=Web Page Zoom Scale WebWidth=Web Page Width -WowAsExample=Weibo of Wow As Example +WowAsExample=Wow As Example ScreenWidth=Screen Width PageWidth=Page Width A4Landscape=A4 Landscape @@ -868,7 +868,7 @@ ImageManufactureBatchEffects=Manufacture Image - Batch - Effects Posterizing=Posterizing SmallValue=Small Value BigValue=Big Value -ThresholdingComments=The color components of the destination image will contain either the small value or the big value.\nFor example, when the small value is 0 and the big value 255, after processed, the red, green, and blue values of the pixels will be either 0 or 255. \nThus, the processed image can only contain the following colors:\n black (red = 0, green = 0, blue = 0)\n white (red = 255, green = 255, blue = 255)\n red (red = 255, green = 0, blue = 0)\n green (red = 0, green = 255, blue = 0)\n blue (red = 0, green = 0, blue = 255)\n yellow (red = 255, green = 255, blue = 0)\n magenta (red = 255, green = 0, blue = 255)\n cyan (red = 0, green = 255, blue = 255)\n\nYou can use menu "Settings" to show/hide the comments. +ThresholdingComments=The color components of the destination image will contain either the small value or the big value.\nFor example, when the small value is 0 and the big value 255, after processed, \nthe red, green, and blue values of the pixels will be either 0 or 255. \nThus, the processed image can only contain the following colors:\n black (red = 0, green = 0, blue = 0)\n white (red = 255, green = 255, blue = 255)\n red (red = 255, green = 0, blue = 0)\n green (red = 0, green = 255, blue = 0)\n blue (red = 0, green = 0, blue = 255)\n yellow (red = 255, green = 255, blue = 0)\n magenta (red = 255, green = 0, blue = 255)\n cyan (red = 0, green = 255, blue = 255)\n\nYou can use menu "Settings" to show/hide the comments. WeiboAddressComments2=By clicking the account's "Main page", its address will be shown in browser's address input.\nNotice, nick address is NOT true address. Example "\u535a\u7269\u6742\u5fd7" has its nick address "https://weibo.com/bowu"\nbut its valid address is actual "https://weibo.com/p/1002061195054531".\n\nYou can use menu "Settings" to show/hide the comments. SaveCtrl=Save(Ctrl-s) InterfaceStyle=Interface Style @@ -1033,7 +1033,7 @@ ViewAfterSave=View After Save KeepImagesSize=Keep Images Size AllSetAs=All Set As Index=Index -ViewGifComments=This tool ignores "interval" and "loop" defined by the image itself +GifViewTips=This tool ignores "interval" and "loop" defined by the image itself.\n\nShortcuts in this stage\n"CTRL+i" Display the image information.\n"PAGE DOWN" Next frame in this file. \n"PAGE UP" Previous frame in this file. \n"CTRL+1" Zoom the image as its original size. \n"CTRL+2" Zoom the image as the pane's size. \n"CTRL+3" Zoom in the image a little. \n"CTRL+4" Zoom out the image a little. \n"CTRL+m" Show/Hide the comments(Not affect tips). \n"CTRL+-" Decrease font size. \n"CTRL+=" Increase font size. \n"F5" Close the stage. Operation=Operation OpenPathDot=Open Path... Area=Area @@ -1203,7 +1203,6 @@ IncludeAll=Include All NotIncludeAll=Not Include All LineNumber=Line Number DisplayHexadecimalByCurrent=Display Hexadecimal By Current Charset -PaginateComments=When page is changed, part functions are unavaliable before saved EncodeComments=When BOM is detected in file, its charset is definiate FilterTypesComments=Include One : a | b | c\nInclude All: a & b & c\nNot Include Any: !( a | b | c) = !a & !b & !c\nNot Include All : !(a & b & c) = !a | !b | !c TextLineBreakComments=Please filter files to avoid handle line break for binary files that is nonsense. @@ -1219,7 +1218,6 @@ BytesNumber=Bytes Number DetectLineBreak=Detect Line Break Character=Character BytesHex=Bytes(Hexadecimal) -ByteHexComments=Each byte is expressed as 2 characters of hexadecimal, like 05, A1, EF. All spaces, line breaks, and invalid values will be ignored InvalidData=Invalid Data ChangeAsWhenSave=Change As(Take effect when save) LFHex=LF(0A) @@ -1229,15 +1227,13 @@ SeparateByCommaBlanksInvolved=Separate By Comma. Blanks are involved to compare. Count=Count CountNumber=Found {0} matched subStrings. NotSupportFrameSet=Not Support FrameSet -OnlyForDisplayNoEffect=Only for display. No actual effect. -DecodeComments=Charset, line break, and pagination may affect decoding FileCut=Cut File SplitByFilesNumber=Split By Files Number SplitByBytesNumber=Split By Bytes Number CutByStartEndByteList=Cut By "StartByte-EndByte" List -StartEndByteComments=List of "StartByte-EndByte" separated by comma, like "1-4000,67KB-83KB, 15mb-29mb ". From 1. +StartEndByteComments=List of "StartByte-EndByte" separated by comma, like "1-4000,67K-83K, 15m-29m ". 1-Based. FilesGenerated={0} files generated -BytesValuesComments=Valid values like: 5000, 20kb, 60MB, 1GB. +AbbrevValuesComments=Valid values like: 5000, 20k, 60M, 1G. FileMerge=Merge File SnapScreen=Snap Screen Selection=Selection @@ -1247,3 +1243,95 @@ Byte=Byte PdfView=View PDF - Image Mode Select=Select TransparentBackground=Transparent Background +ConfirmWhenDelete=Confirm When Delete +ViewRecordedImages=View Recorded Images +SaveRecordedImages=Save recorded images +SaveOptions=Save Options +StartRecording=Start Recording +ActiveWindow=Active Window +StopRecording=Stop Recording +ImageViewerTips=When "Crop" is selected\uff0c "Copy" and "Save As" are for the selected area.\nTo select area, left click the image to set the Left-Top and right click to set Right-Bottom.\n\nWhen "Crop" is not selected, "Copy" and "Save As" are for whole image.\n\nShortcuts in this stage\n"CTRL+c" Copy the image or its cropped area to system clipboard.\n"CTRL+s"\t Save the image or its cropped area as an image file.\n"CTRL+d / DELETE" Delete the image file.\n"CTRL+i" Display the image information.\n"CTRL+a" Select all of the image.\n"PAGE DOWN" Next image in same directory. \n"PAGE UP" Previous image in same directory. \n"CTRL+1" Zoom the image as its original size. \n"CTRL+2" Zoom the image as the pane's size. \n"CTRL+3" Zoom in the image a little. \n"CTRL+4" Zoom out the image a little. \n"CTRL+m" Show/Hide the comments(Not affect tips). \n"CTRL+-" Decrease font size. \n"CTRL+=" Increase font size. \n"F5" Close the stage. +RecordingImages={0} images have been recorded. Waiting for new images... +RecordImagesTips=When "Start" is clicked, the tool will monitor images in system clipboard and save/display them.\n\nImages in system clipboard come from screenshots or pictures generated from softwares like operation "CTRL+c".\n\nOn Windows, shortcuts to make screenshots:\n"PrintScreen" Make snapshot of full screen.\n"Alt+PrintScreen" Make snapshot of current active window.\n\nOn Linux, shortcuts to make screenshots:\n"Ctrl+PrintScreen" Make snapshot of full screen.\n"Ctrl+Alt+PrintScreen" Make snapshot of current active window.\n"Shift+Ctrl+PrintScreen" Make snapshot of selected area.\n\nOn Mac, shortcuts to make screenshots:\n"Command+Control+Shift+3" Make snapshot of full screen.\n"Command+Control+Shift+4" Make snapshot of selected area.\n"Command+Control+Shift+4+Spacebar" Make snapshot of current active window.\n +RecordImagesInSystemClipBoard=Record Images In System Clipboard +DirectoryReserved=This is reserved directory of MyBox. +ImagesBrowser=Browse Images +Manufacture=Manufacture +PdfViewTips=When "Crop" is selected, "Copy" and "Save As" are for the selected area.\nTo select area, left click the image to set the Left-Top and right click to set Right-Bottom.\n\nWhen "Crop" is not selected, "Copy" and "Save As" are for whole image.\n\nShortcuts in this stage:\n"CTRL+i" Display the file information.\n"CTRL+c" Copy the image or its cropped area to system clipboard.\n"CTRL+s"\t Save the image or its cropped area as an image file.\n"CTRL+a" Select all of the image.\n"PAGE DOWN" Next page of this file. \n"PAGE UP" Previous page of this file. \n"HOME" First page of this file. \n"END" Last page of this file. \n"CTRL+1" Zoom the image as its original size. \n"CTRL+2" Zoom the image as the pane's size. \n"CTRL+3" Zoom in the image a little. \n"CTRL+4" Zoom out the image a little. \n"CTRL+m" Show/Hide the comments(Not affect tips). \n"CTRL+-" Decrease font size. \n"CTRL+=" Increase font size. \n"F5" Close the stage. +ImageBrowserTips=Click an image to select it, and click it again to unselect it.\nDouble click an image to view it in new stage.\n\nWhen images are selected, zoom/rotation/movement/deletion are for the selected images.\nWhen only one image is selected, View/Rename/Information works.\nWhen no image is selected, zoom/rotation/movement are for all images in this stage.\n\nShortcuts in this stage\n"CTRL+1" Zoom images as their original size. \n"CTRL+2" Zoom images as their pane's size. \n"CTRL+3" Zoom in images a little. \n"CTRL+4" Zoom out images a little. \n"CTRL+i" Display selected image's information.\n"CTRL+d / DELETE" Delete selected image files.\n"PAGE DOWN" Next batch of images in same directory. \n"PAGE UP" Previous batch of images in same directory. \n"CTRL+m" Show/Hide the comments(Not affect tips). \n"CTRL+-" Decrease font size. \n"CTRL+=" Increase font size. \n"F5" Close the stage. +BytesEditerTips=All spaces, line breaks, and invalid values will be ignored\u3002\nLine breaks are only for displaying and do not effect bytes values.\n\nWhen "Decode" under Text tab is checked, bytes are decoded with the selected character set.\nBytes' decoding is affected by charset, line break, and pagination.\nThe decoded texts are shown in the right pane, and can be scrolled synchronously with the bytes of left pane.\nWhen some bytes are selected in left, corresponding decoded texts are highlighted in right.\n\nWhen bytes in page are modified, part functions are unavaliable before changes are saved.\n\nShortcuts in this stage\n"CTRL+c" Copy selected bytes to system clipboard.\n"CTRL+v" Paste strings of system clipboard.\n"CTRL+x" Cut selected bytes and copy to system clipboard.\n"CTRL+d / DELETE" Delete selected bytes.\n"CTRL+a" Select all of bytes in this page.\n"CTRL+s"\t Save modifications.\n"CTRL+z" Undo last modification.\n"CTRL+y" Redo last modification.\n"CTRL+r" Discard unsaved modifications and recover to original page.\n"CTRL+f"\t Find first. (Under Find/Replace tab)\n"CTRL+l" Find last. (Under Find/Replace tab)\n"CTRL+n" Find next. (Under Find/Replace tab)\n"CTRL+p" Find previous. (Under Find/Replace tab)\n"CTRL+e" Replace. (Under Find/Replace tab)\n"PAGE DOWN" Next page of this file. \n"PAGE UP" Previous page of this file. \n"HOME" First page of this file. \n"END" Last page of this file. \n"CTRL+m" Show/Hide the comments(Not affect tips). \n"CTRL+-" Decrease font size. \n"CTRL+=" Increase font size. \n"F5" Close the stage. +TextEditerTips=Character Set and Line Break can be changed and take effect when file is saved. \n\nWhen "Display Hexadecimal" under Bytes tab is checked, texts are encoded with current character set.\nThe encoded bytes are shown in the right pane, and can be scrolled synchronously with the texts of left pane.\nWhen some texts are selected in left, corresponding encoded bytes are highlighted in right.\n\nWhen texts in page are modified, part functions are unavaliable before changes are saved.\n\nShortcuts in this stage\n"CTRL+c" Copy selected texts to system clipboard.\n"CTRL+v" Paste strings of system clipboard.\n"CTRL+x" Cut selected texts and copy to system clipboard.\n"CTRL+d / DELETE" Delete selected texts.\n"CTRL+a" Select all of texts in this page.\n"CTRL+s"\t Save modifications.\n"CTRL+z" Undo last modification.\n"CTRL+y" Redo last modification.\n"CTRL+r" Discard unsaved modifications and recover to original page.\n"CTRL+f"\t Find first. (Under Find/Replace tab)\n"CTRL+l" Find last. (Under Find/Replace tab)\n"CTRL+n" Find next. (Under Find/Replace tab)\n"CTRL+p" Find previous. (Under Find/Replace tab)\n"CTRL+e" Replace. (Under Find/Replace tab)\n"PAGE DOWN" Next page of this file. \n"PAGE UP" Previous page of this file. \n"HOME" First page of this file. \n"END" Last page of this file. \n"CTRL+m" Show/Hide the comments(Not affect tips). \n"CTRL+-" Decrease font size. \n"CTRL+=" Increase font size. \n"F5" Close the stage. +WhenNewImageInSystemBoard=When new image appears in system board +SaveAndView=Save And View +RecordOptions=Record Options +ImageCalculation=Calculate Image +GreyHistogram=Grey Histogram +RedHistogram=Red Histogram +GreenHistogram=Green Histogram +BlueHistogram=Blue Histogram +OpacityHistogram=Opacity Histogram +HueHistogram=Hue Histogram +SaturationHistogram=Saturation Histogram +BrightnessHistogram=Brightness Histogram +Histogram=Histogram +Data=Data +PixelsNumber=Pixels Number +DataType=Data Type +Greyscale=Greyscale +GreyValue=Grey Value +ImageStatistic=Image Statistic +StatisticValue=Statistic Value +OccurrenceNumber=Occurrence Number +Median=Median +Statistic=Statistic +Percentage=Percentage +Sum=Sum +Showcase=Showcase +Sequence=Sequence +OrderSequence=Order Sequence +HueGrades=Hue Grades +BrightnessGrades=Brightness Grades +SaturationGrades=Saturation Grades +DataNumber=Data Number +Algorithm=Algorithm +Palette=Palette +Division=Division +Mod=Mod +MedianCut=Median Cut +kMeansClustering=k-Means Clustering +ColorsNumber=Colors Number +RGBUniformQuantization=RGB Uniform Quantization +HSBUniformQuantization=HSB Uniform Quantization +ColorHistogram=Color Histogram +ColorPie=Color Pie +ColorQuantization=Color Quantization +Mode=Mode +CategoryNumber=Category Number +Dithering=Dithering +QuantizationComments=Technique of reducing distinct colors in image is called "Color Quantization".\n"Dithering" is to optimzie the result of Color Quantization. It only works for whole image. +Variance=Variance +Skewness=Skewness +Mean=Mean +ColorFeatures=Color Features +BWThresholdComments=Threshold should be between 0 and 255, and can be empty to use default value. \nDithering only works for whole image. +Pop=Pop +Ref=Ref +BOMcomments=BOM(Byte Order Marks) is 2 or 3 bytes in head of the file for UTF-16 or UTF-32.\nSome UTF-8 files have BOM written by some Windows programs which can confuse other platforms. +FontSize12=Font Size 12px +FontSize15=Font Size 15px +FontSize17=Font Size 17px +DitherComments=Dithering is a technique to diffuse quantization error to avoid color banding.\nIt may improve image quality after color quantization(Reduce colors in palette). +Contrast=Contrast +HistogramEqualization=Histogram Equalization +SampleSize=Sample Size +HSBHistogramEqualization=HSB Histogram Equalization +GrayHistogramEqualization=Gray Histogram Equalization +AdaptiveHistogramEqualization=Adaptive Histogram Equalization +GrayHistogramShifting=Gray Histogram Shifting +Offset=Offset +LumaHistogramEqualization=Luma Histogram Equalization +GrayHistogramStretching=Gray Histogram Stretching +LeftThreshold=Left Threshold +RightThreshold=Right Threshold +ColorMoments=Color Moments +Grey=Grey diff --git a/MyBox/src/main/resources/bundles/Messages_zh_CN.properties b/MyBox/src/main/resources/bundles/Messages_zh_CN.properties index a252fd98e..a65d5e751 100644 --- a/MyBox/src/main/resources/bundles/Messages_zh_CN.properties +++ b/MyBox/src/main/resources/bundles/Messages_zh_CN.properties @@ -221,7 +221,7 @@ Darker=\u6697\u6de1 Brighter=\u660e\u4eae Recover=\u6062\u590d Save=\u4fdd\u5b58 -SaveAs=\u53e6\u5b58 +SaveAs=\u4fdd\u5b58\u4e3a SureOverrideFile=\u786e\u5b9e\u8981\u8986\u76d6\u539f\u6587\u4ef6\u5417\uff1f InsertPageSeparator=\u63d2\u5165\u9875\u5206\u9694\u884c InsertPageSeparatorComments=\u53ef\u4ee5\u7f16\u8f91\u5206\u9694\u884c\uff0c\u4f46\u4e0d\u8981\u4fee\u6539\u201c\u201d\u548c\u201c\u201d\uff0c\u5b83\u4eec\u7528\u6765\u81ea\u52a8\u63d2\u5165\u771f\u5b9e\u7684\u9875\u7801\u548c\u9875\u6570 @@ -429,7 +429,7 @@ OK=\u786e\u5b9a PaneSize=\u9762\u677f\u5c3a\u5bf8 CurrentPixels=\u5f53\u524d\u50cf\u7d20 Tips=\u5c0f\u63d0\u793a -ImageManufactureTips=\u5229\u7528\u672c\u529f\u80fd\u53ef\u4ee5\u67e5\u770b\u3001\u6d4f\u89c8\u3001\u548c\u5904\u7406\u56fe\u50cf\u3002\n\n\u201c\u653e\u5927\u201d\u3001\u201c\u7f29\u5c0f\u201d\u6309\u94ae\u4ee5\u53ca\u201c\u67e5\u770b\u201d\u9875\u7b7e\u4e0b\u7684\u79fb\u52a8\u6309\u94ae\uff0c\u53ea\u6539\u53d8\u56fe\u50cf\u7684\u663e\u793a\uff0c\u800c\u4e0d\u6539\u53d8\u56fe\u50cf\u672c\u8eab\u3002\n\u8981\u6539\u53d8\u56fe\u50cf\u7684\u5927\u5c0f\u3001\u8272\u5f69\u3001\u5f62\u72b6\uff0c\u8bf7\u4f7f\u7528\u5176\u5b83\u9875\u7b7e\u4e0b\u7684\u529f\u80fd\u3002\n\n\u70b9\u51fb\u201c\u4fdd\u5b58\u201d(CTRL-s)\u6309\u94ae\u4ee5\u5c06\u6240\u6709\u4fee\u6539\u5199\u5165\u56fe\u50cf\u6587\u4ef6\u3002\u70b9\u51fb\u201c\u6062\u590d\u201d\u6309\u94ae\u53ef\u4ee5\u4e22\u5f03\u5168\u90e8\u4fee\u6539\u3001\u8fd4\u56de\u539f\u56fe\u3002\n\u70b9\u51fb\u201c\u64a4\u9500\u201d(CTRL-z)/\u201c\u91cd\u505a\u201d(CTRL-y)\u6309\u94ae\u53ef\u4ee5\u653e\u5f03/\u8fd4\u56de\u4e0a\u4e00\u6b65\u64cd\u4f5c\u3002\n\u201c\u5386\u53f2\u201d(CTRL-h)\u53ef\u4ee5\u7528\u8fd4\u56de\u5230\u4ee5\u524d\u7684\u4fee\u6539\u3002\n\u5feb\u6377\u952e "CTRL-c"\u53ef\u4ee5\u5c06\u5f53\u524d\u56fe\u50cf\u590d\u5236\u5230\u7cfb\u7edf\u7c98\u8d34\u677f\u3002\n\n\u5e95\u90e8\u663e\u793a\u56fe\u50cf\u7684\u57fa\u672c\u5c5e\u6027\u3002\u8fd8\u672a\u4fdd\u5b58\u7684\u5df2\u4fee\u6539\u7684\u50cf\u7d20\u503c\u4e5f\u88ab\u663e\u793a\u3002\n\n\u4e00\u4e9b\u56fe\u50cf\u683c\u5f0f\uff0c\u5982jpg\\bmp\\gif\uff0c\u4e0d\u652f\u6301\u900f\u660e\u901a\u9053\uff0c\u56e0\u6b64\u201c\u4e0d\u900f\u660e\u5ea6\u201d\u529f\u80fd\u5bf9\u8fd9\u4e9b\u56fe\u50cf\u4e0d\u53ef\u7528\u3002\n\n\u5feb\u6377\u952e\u5b9a\u4e49\u5982\u4e0b:\n"\u56fe\u50cf\u5c3a\u5bf8": CTRL+"1" "\u9762\u677f\u5c3a\u5bf8": CTRL+"2" "\u653e\u5927": CTRL+"3" "\u7f29\u5c0f": CTRL+"4" \n"\u4fdd\u5b58": CTRL+"s" "\u6062\u590d": CTRL+"r" "\u64a4\u9500": CTRL+"z" "\u91cd\u505a": CTRL+"y" \n"\u5386\u53f2": CTRL+"h" "\u590d\u5236": CTRL+"c" \n\n\u663e\u793a/\u9690\u85cf\u6ce8\u91ca: CTRL+"m" (\u4e0d\u5305\u62ec\u6211) +ImageManufactureTips=\u7f29\u653e\u548c\u79fb\u52a8\u4e0d\u6539\u53d8\u56fe\u50cf\u672c\u8eab\u3002\u8981\u4fee\u6539\u56fe\u50cf\u7684\u5927\u5c0f\u3001\u989c\u8272\u3001\u5f62\u72b6\uff0c\u8bf7\u4f7f\u7528\u5404\u9875\u7b7e\u4e0b\u7684\u529f\u80fd\u3002\n\n\u56fe\u50cf\u683c\u5f0f\u5982jpg\\bmp\\gif\u4e0d\u652f\u6301\u900f\u660e\u901a\u9053\uff0c\u56e0\u6b64\u201c\u4e0d\u900f\u660e\u5ea6\u201d/\u201c\u900f\u660e\u5ea6\u201d\u5bf9\u5b83\u4eec\u4e0d\u53ef\u7528\u3002\n\n\u56fe\u50cf\u5c06\u88ab\u4fdd\u5b58\u4e3a8\u4f4d\u7684RGB/ARGB\u683c\u5f0f\uff0c\u5373\u4f7f\u88ab\u8f6c\u53d8\u4e3a\u7070\u8272\u6216\u8005\u9ed1\u767d\u8272\u3002\n\u82e5\u8981\u538b\u7f29\u56fe\u50cf\u6587\u4ef6\uff0c\u8bf7\u4f7f\u7528\u5de5\u5177\u201c\u8f6c\u6362\u56fe\u50cf\u201d\u3002\n\n\u672c\u7a97\u53e3\u7684\u5feb\u6377\u952e\u5982\u4e0b\uff1a\n"CTRL+z" \u64a4\u9500\u4e0a\u4e00\u6b21\u4fee\u6539\u3002\n"CTRL+y" \u6062\u590d\u4e0a\u4e00\u6b21\u4fee\u6539\u3002\n"CTRL+r" \u653e\u5f03\u6240\u6709\u4fee\u6539\u3001\u8fd4\u56de\u539f\u56fe\u3002\n"CTRL+c" \u5c06\u56fe\u50cf\u6216\u5b83\u7684\u526a\u5207\u90e8\u5206\u590d\u5236\u5230\u7cfb\u7edf\u7c98\u8d34\u677f\u3002\n"CTRL+s"\t \u4fdd\u5b58\u5bf9\u56fe\u50cf\u7684\u4fee\u6539\u3002\n"CTRL+g"\t \u786e\u5b9a\uff08\u5982\u679c\u6709\uff09\u3002\n"CTRL+i" \u663e\u793a\u56fe\u50cf\u4fe1\u606f\u3002\n"CTRL+h" \u663e\u793a\u56fe\u50cf\u7684\u4fee\u6539\u5386\u53f2\u5217\u8868\u3002\n"CTRL+1" \u663e\u793a\u56fe\u50cf\u7684\u539f\u59cb\u5c3a\u5bf8\u3002\n"CTRL+2" \u628a\u56fe\u50cf\u7f29\u653e\u5230\u7a97\u53e3\u5c3a\u5bf8\u3002 \n"CTRL+3" \u653e\u5927\u56fe\u50cf\u3002 \n"CTRL+4" \u7f29\u5c0f\u56fe\u50cf\u3002\n"CTRL+p" \u5f39\u51fa\u65b0\u7a97\u53e3\u4ee5\u663e\u793a\u5f53\u524d\u56fe\u50cf\u3002 \n"CTRL+f" \u628a\u5f53\u524d\u56fe\u50cf\u8bbe\u7f6e\u4e3a\u53c2\u8003\u56fe\u3002 \n"CTRL+q" \u8bbe\u7f6e\u5f53\u524d\u56fe\u50cf\u7684\u989c\u8272\u503c\u3002 \uff08\u5728\u201c\u8272\u5f69\u201d\u9875\u7b7e\u4e0b\uff09 \n"CTRL+w" \u589e\u52a0\u5f53\u524d\u56fe\u50cf\u7684\u989c\u8272\u503c\u3002 \uff08\u5728\u201c\u8272\u5f69\u201d\u9875\u7b7e\u4e0b\uff09 \n"CTRL+e" \u51cf\u5c11\u5f53\u524d\u56fe\u50cf\u7684\u989c\u8272\u503c\u3002 \uff08\u5728\u201c\u8272\u5f69\u201d\u9875\u7b7e\u4e0b\uff09 \n"PAGE DOWN" \u540c\u4e00\u76ee\u5f55\u4e0b\u7684\u4e0b\u4e00\u4e2a\u56fe\u50cf\u6587\u4ef6\u3002\uff08\u5728\u201c\u6d4f\u89c8\u201d\u9875\u7b7e\u4e0b\uff09 \n"PAGE UP" \u540c\u4e00\u76ee\u5f55\u4e0b\u7684\u4e0a\u4e00\u4e2a\u56fe\u50cf\u6587\u4ef6\u3002\uff08\u5728\u201c\u6d4f\u89c8\u201d\u9875\u7b7e\u4e0b\uff09 \n"CTRL+m" \u663e\u793a/\u9690\u85cf\u6ce8\u91ca\uff08\u4e0d\u5f71\u54cd\u5c0f\u63d0\u793a\uff09 \n"CTRL+-" \u51cf\u5c0f\u5b57\u4f53\u5927\u5c0f\u3002\n"CTRL+=" \u589e\u52a0\u5b57\u4f53\u5927\u5c0f \u3002\n"F5" \u5173\u95ed\u6b64\u7a97\u53e3\u3002 ColorPalette=\u8c03\u8272\u76d8 Hexadecimal=\u5341\u516d\u8fdb\u5236 Green=\u7eff\u8272 @@ -512,7 +512,7 @@ Scope...=\u8303\u56f4... Set=\u8bbe\u7f6e Scope=\u8303\u56f4 Value=\u503c -ColorMatchComments=\u5982\u4f55\u5339\u914d\u989c\u8272\uff1a\n1\uff09\u201c\u8272\u5f69\u8ddd\u79bb\u201d\u6216\u8005\u201c\u8272\u76f8\u8ddd\u79bb\u201d\u8868\u660e\u4e24\u4e2a\u989c\u8272\u7684\u5dee\u522b\u3002\n \u201c\u989c\u8272\u5dee\u522b\u201d\u7684\u5b9a\u4e49\u53ef\u4ee5\u53c2\u8003"https://en.wikipedia.org/wiki/Color_difference"\n2\uff09\u5f53\u989c\u8272\u8ddd\u79bb\u5c0f\u4e8e\u5b9a\u4e49\u7684\u8ddd\u79bb\u503c\u65f6\uff0c\u610f\u5473\u7740\u4e24\u79cd\u989c\u8272\u662f\u201c\u5339\u914d\u7684\u201d\u3002\n3\uff09\u5f53\u989c\u8272\u8ddd\u79bb\u5b9a\u4e49\u4e3a\u96f6\u65f6\uff0c\u5219\u610f\u5473\u7740\u989c\u8272\u662f\u7cbe\u786e\u5339\u914d\u7684\u3002\n4\uff09\u53ef\u4ee5\u9009\u62e9\u591a\u4e2a\u989c\u8272\u6765\u6bd4\u8f83\u56fe\u50cf\u4e2d\u7684\u50cf\u7d20\u3002\n \u5b83\u4eec\u7684\u5173\u7cfb\u662f\u201c\u6216\u201d\uff0c\u5373\u50cf\u7d20\u7684\u8272\u5f69\u53ef\u4ee5\u4e0e\u4efb\u610f\u88ab\u9009\u7684\u8272\u5f69\u8fdb\u884c\u6bd4\u8f83\u3002\n\n\u53ef\u4ee5\u7528\u5feb\u6377\u952e\u201cCTRL-m\u201d\u6765\u663e\u793a/\u9690\u85cf\u63d0\u793a\u3002 +ColorMatchComments=\u5982\u4f55\u5339\u914d\u989c\u8272\uff1a\n1\uff09\u201c\u8272\u5f69\u8ddd\u79bb\u201d\u6216\u8005\u201c\u8272\u76f8\u8ddd\u79bb\u201d\u8868\u660e\u4e24\u4e2a\u989c\u8272\u7684\u5dee\u522b\u3002\n \u201c\u989c\u8272\u5dee\u522b\u201d\u7684\u5b9a\u4e49\u53ef\u4ee5\u53c2\u8003"https://en.wikipedia.org/wiki/Color_difference"\n2\uff09\u5f53\u989c\u8272\u8ddd\u79bb\u5c0f\u4e8e\u5b9a\u4e49\u7684\u8ddd\u79bb\u503c\u65f6\uff0c\u610f\u5473\u7740\u4e24\u79cd\u989c\u8272\u662f\u201c\u5339\u914d\u7684\u201d\u3002\n3\uff09\u5f53\u989c\u8272\u8ddd\u79bb\u5b9a\u4e49\u4e3a\u96f6\u65f6\uff0c\u5219\u610f\u5473\u7740\u989c\u8272\u662f\u7cbe\u786e\u5339\u914d\u7684\u3002\n4\uff09\u53ef\u4ee5\u9009\u62e9\u591a\u4e2a\u989c\u8272\u6765\u6bd4\u8f83\u56fe\u50cf\u4e2d\u7684\u50cf\u7d20\u3002\n \u5b83\u4eec\u7684\u5173\u7cfb\u662f\u201c\u6216\u201d\uff0c\u5373\u50cf\u7d20\u7684\u8272\u5f69\u53ef\u4ee5\u4e0e\u4efb\u610f\u88ab\u9009\u7684\u8272\u5f69\u8fdb\u884c\u6bd4\u8f83\u3002\n\n\u53ef\u4ee5\u7528\u5feb\u6377\u952e\u201cCTRL+m\u201d\u6765\u663e\u793a/\u9690\u85cf\u63d0\u793a\u3002 ContinueClickColor=\u70b9\u51fb\u4e0d\u540c\u7684\u50cf\u7d20\u4ee5\u8bfb\u53d6\u66f4\u591a\u989c\u8272\u3002 InvalidRectangle=\u975e\u6cd5\u533a\u57df\u3002\u201c\u5de6\u4e0a\u89d2\u201d\u5e94\u5f53\u6bd4\u201c\u53f3\u4e0b\u89d2\u201d\u5c0f\u3002 LineColor=\u7ebf\u6761\u989c\u8272 @@ -646,7 +646,7 @@ SplitPdf=\u5206\u5272PDF\u6587\u4ef6 PagesNumberOfEachFile=\u6bcf\u4e2a\u6587\u4ef6\u7684\u9875\u6570 NumberOfFilesDividedEqually=\u5747\u5206\u7684\u6587\u4ef6\u6570 StartEndList=\u8d77\u6b62\u5217\u8868 -StartEndComments="\u5f00\u59cb-\u7ed3\u675f"\u5217\u8868\uff0c\u4ee5\u82f1\u6587\u9017\u53f7\u5206\u5272\uff0c\u5982"1-4,67-83, 15-29"\u3002\u4ece1\u5f00\u59cb\u3002 +StartEndComments="\u5f00\u59cb-\u7ed3\u675f"\u5217\u8868\uff0c\u4ee5\u82f1\u6587\u9017\u53f7\u5206\u5272\uff0c\u5982"1-4,67-83, 15-29"\u3002\u4ee51\u8d77\u59cb\u3002 WrongStartEnd=\u4ee5\u4e0b"Start-End"\u975e\u6cd5: FilesGeneratedUnder=\u4ee5\u4e0b\u6587\u4ef6\u5df2\u751f\u6210\u5728\u76ee\u5f55 NetworkTools=\u7f51\u7edc\u5de5\u5177 @@ -865,7 +865,7 @@ Thresholding=\u9608\u503c\u5316 Minimum=\u6700\u5c0f\u503c Maximum=\u6700\u5927\u503c ImageManufactureBatchEffects=\u5904\u7406\u56fe\u50cf-\u6279\u91cf-\u6548\u679c -Posterizing=\u6d77\u62a5\uff08\u51cf\u8272\uff09 +Posterizing=\u6d77\u62a5\u5316 SmallValue=\u5c0f\u503c BigValue=\u5927\u503c ThresholdingComments=\u76ee\u6807\u56fe\u50cf\u7684\u989c\u8272\u901a\u9053\u5c06\u53ea\u5305\u542b\u5c0f\u503c\u6216\u8005\u5927\u503c\u3002\n\u4f8b\u5982\uff0c\u82e5\u5c0f\u503c\u4e3a0\u4e14\u5927\u503c\u4e3a255\uff0c\u5f53\u56fe\u50cf\u5904\u7406\u5b8c\u6bd5\uff0c\u50cf\u7d20\u7684\u7ea2\u84dd\u7eff\u503c\u4e0d\u662f0\u5c31\u662f255\u3002\n\u56e0\u6b64\uff0c\u5904\u7406\u540e\u7684\u56fe\u50cf\u53ea\u5305\u542b\u4ee5\u4e0b\u989c\u8272\uff1a\n \u9ed1\u8272(red = 0, green = 0, blue = 0)\n \u767d\u8272(red = 255, green = 255, blue = 255)\n \u7ea2\u8272(red = 255, green = 0, blue = 0)\n \u7eff\u8272(red = 0, green = 255, blue = 0)\n \u84dd\u8272(red = 0, green = 0, blue = 255)\n \u9ec4\u8272(red = 255, green = 255, blue = 0)\n \u6a59\u8272(red = 255, green = 0, blue = 255)\n \u9752\u8272(red = 0, green = 255, blue = 255)\n\n\u4f60\u53ef\u4ee5\u4f7f\u7528\u83dc\u5355\u201c\u8bbe\u7f6e\u201d\u6765\u663e\u793a/\u9690\u85cf\u63d0\u793a\u3002 @@ -1033,7 +1033,7 @@ ViewAfterSave=\u4fdd\u5b58\u540e\u67e5\u770b KeepImagesSize=\u4fdd\u6301\u56fe\u50cf\u5c3a\u5bf8 AllSetAs=\u90fd\u8bbe\u7f6e\u4e3a Index=\u7d22\u5f15 -ViewGifComments=\u672c\u5de5\u5177\u5ffd\u7565\u56fe\u7247\u81ea\u8eab\u5b9a\u4e49\u7684\u95f4\u9694\u548c\u5faa\u73af\u5c5e\u6027 +GifViewTips=\u672c\u5de5\u5177\u5ffd\u7565\u56fe\u7247\u81ea\u8eab\u5b9a\u4e49\u7684\u95f4\u9694\u548c\u5faa\u73af\u5c5e\u6027\u3002\n\n\u6b64\u7a97\u53e3\u7684\u5feb\u6377\u952e\u5982\u4e0b\uff1a\n"CTRL+i" \u663e\u793a\u56fe\u50cf\u4fe1\u606f\u3002\n"PAGE DOWN" \u6b64\u6587\u4ef6\u4e2d\u7684\u4e0b\u4e00\u5e27\u56fe\u50cf\u3002 \n"PAGE UP" \u6b64\u6587\u4ef6\u4e2d\u7684\u4e0a\u4e00\u5e27\u56fe\u50cf\u3002 \n"CTRL+1" \u663e\u793a\u56fe\u50cf\u7684\u539f\u59cb\u5c3a\u5bf8\u3002\n"CTRL+2" \u628a\u56fe\u50cf\u7f29\u653e\u5230\u7a97\u53e3\u5c3a\u5bf8\u3002 \n"CTRL+3" \u653e\u5927\u56fe\u50cf\u3002 \n"CTRL+4" \u7f29\u5c0f\u56fe\u50cf\u3002\n"CTRL+m" \u663e\u793a/\u9690\u85cf\u6ce8\u91ca\uff08\u4e0d\u5f71\u54cd\u5c0f\u63d0\u793a\uff09\u3002 \n"CTRL+-" \u51cf\u5c0f\u5b57\u4f53\u5927\u5c0f\u3002\n"CTRL+=" \u589e\u52a0\u5b57\u4f53\u5927\u5c0f \u3002\n"F5" \u5173\u95ed\u6b64\u7a97\u53e3\u3002 Operation=\u64cd\u4f5c OpenPathDot=\u6253\u5f00\u76ee\u5f55... Area=\u533a\u57df @@ -1203,7 +1203,6 @@ IncludeAll=\u5305\u542b\u6240\u6709 NotIncludeAll=\u4e0d\u542b\u6240\u6709 LineNumber=\u884c\u53f7 DisplayHexadecimalByCurrent=\u663e\u793a\u57fa\u4e8e\u5f53\u524d\u5b57\u7b26\u96c6\u7684\u5341\u516d\u8fdb\u5236 -PaginateComments=\u5f53\u9875\u9762\u88ab\u4fee\u6539\u65f6\uff0c\u5728\u4fdd\u5b58\u4e4b\u524d\u90e8\u5206\u529f\u80fd\u4e0d\u53ef\u7528 EncodeComments=\u5f53\u68c0\u6d4b\u5230\u6587\u4ef6\u4e2d\u5305\u542bBOM\uff0c\u5219\u6587\u4ef6\u5b57\u7b26\u96c6\u662f\u660e\u786e\u7684 FilterTypesComments=\u5305\u542b\u4efb\u4e00\uff1a a | b | c\n\u5305\u542b\u6240\u6709\uff1a a & b & c\n\u4e0d\u542b\u4efb\u4e00\uff1a !( a | b | c) = !a & !b & !c\n\u4e0d\u542b\u6240\u6709\uff1a !(a & b & c) = !a | !b | !c TextLineBreakComments=\u8bf7\u8fc7\u6ee4\u6587\u4ef6\u4ee5\u907f\u514d\u5bf9\u4e8c\u8fdb\u5236\u6587\u4ef6\u5904\u7406\u6362\u884c\u7b26\uff08\u90a3\u6837\u6ca1\u6709\u610f\u4e49\uff09\u3002 @@ -1219,7 +1218,6 @@ BytesNumber=\u5b57\u8282\u6570 DetectLineBreak=\u68c0\u6d4b\u6362\u884c\u7b26 Character=\u5b57\u7b26 BytesHex=\u5b57\u8282\uff08\u5341\u516d\u8fdb\u5236\uff09 -ByteHexComments=\u6bcf\u4e2a\u5b57\u8282\u88ab\u8868\u793a\u4e3a\u5341\u516d\u8fdb\u5236\u7684\u4e24\u4e2a\u5b57\u7b26, \u598205, A1, EF\u3002\u6240\u6709\u7684\u7a7a\u683c\u3001\u6362\u884c\u3001\u548c\u975e\u6cd5\u6570\u503c\u90fd\u88ab\u5ffd\u7565 InvalidData=\u975e\u6cd5\u6570\u636e ChangeAsWhenSave=\u4fee\u6539\u4e3a\uff08\u4fdd\u5b58\u65f6\u751f\u6548\uff09 LFHex=LF(0A) @@ -1229,15 +1227,13 @@ SeparateByCommaBlanksInvolved=\u4ee5\u9017\u53f7\u5206\u5272\u3002\u7a7a\u683c\u Count=\u8ba1\u6570 CountNumber=\u53d1\u73b0{0}\u4e2a\u5339\u914d\u7684\u5b50\u4e32\u3002 NotSupportFrameSet=\u4e0d\u652f\u6301FrameSet -OnlyForDisplayNoEffect=\u4ec5\u7528\u4e8e\u663e\u793a\u3002\u65e0\u5b9e\u9645\u5f71\u54cd\u3002 -DecodeComments=\u5b57\u7b26\u96c6\u3001\u6362\u884c\u3001\u5206\u9875\u90fd\u4f1a\u5f71\u54cd\u89e3\u7801 FileCut=\u526a\u5207\u6587\u4ef6 SplitByFilesNumber=\u6309\u6587\u4ef6\u6570\u5206\u5272 SplitByBytesNumber=\u6309\u5b57\u8282\u6570\u5206\u5272 CutByStartEndByteList=\u6309\u201c\u5f00\u59cb\u5b57\u8282-\u7ed3\u675f\u5b57\u8282\u201d\u5217\u8868\u526a\u5207 -StartEndByteComments=\u201c\u5f00\u59cb\u5b57\u8282-\u7ed3\u675f\u5b57\u8282\u201d\u5217\u8868\uff0c\u4ee5\u82f1\u6587\u9017\u53f7\u5206\u9694\uff0c\u5982\u201c1-4000,67KB-83KB, 15mb-29mb\u201d\u3002\u4ece1\u5f00\u59cb\u3002 +StartEndByteComments=\u201c\u5f00\u59cb\u5b57\u8282-\u7ed3\u675f\u5b57\u8282\u201d\u5217\u8868\uff0c\u4ee5\u82f1\u6587\u9017\u53f7\u5206\u9694\uff0c\u5982\u201c1-4000,67K-83K, 15m-29m\u201d\u3002\u4ee51\u8d77\u59cb\u3002 FilesGenerated=\u751f\u6210{0}\u4e2a\u6587\u4ef6 -BytesValuesComments=\u5408\u6cd5\u503c\u5982\uff1a5000, 20kb, 60MB, 1GB\u3002 +AbbrevValuesComments=\u5408\u6cd5\u503c\u5982\uff1a5000, 20k, 60M, 1G\u3002 FileMerge=\u5408\u5e76\u6587\u4ef6 SnapScreen=\u622a\u5c4f Selection=\u9009\u62e9 @@ -1247,3 +1243,95 @@ Byte=\u5b57\u8282 PdfView=\u67e5\u770bPDF-\u56fe\u50cf\u6a21\u5f0f Select=\u9009\u62e9 TransparentBackground=\u900f\u660e\u80cc\u666f +ConfirmWhenDelete=\u5220\u9664\u65f6\u786e\u8ba4 +ViewRecordedImages=\u67e5\u770b\u8bb0\u5f55\u7684\u56fe\u50cf +SaveRecordedImages=\u4fdd\u5b58\u8bb0\u5f55\u7684\u56fe\u50cf +SaveOptions=\u4fdd\u5b58\u9009\u9879 +StartRecording=\u5f00\u59cb\u8bb0\u5f55 +ActiveWindow=\u6d3b\u8dc3\u7684\u7a97\u53e3 +StopRecording=\u505c\u6b62\u8bb0\u5f55 +ImageViewerTips=\u5f53\u201c\u526a\u5207\u201d\u88ab\u9009\u62e9\u65f6,\u201c\u590d\u5236\u201d\u548c\u201c\u4fdd\u5b58\u4e3a\u201d\u662f\u9488\u5bf9\u88ab\u9009\u62e9\u533a\u57df\u7684\u3002\n\u9009\u62e9\u533a\u57df\uff1a\u5de6\u952e\u70b9\u51fb\u56fe\u50cf\u4ee5\u53d6\u5de6\u4e0a\u89d2\uff0c\u53f3\u952e\u70b9\u51fb\u53d6\u53f3\u4e0b\u89d2\u3002\n\n\u5f53\u201c\u526a\u5207\u201d\u672a\u88ab\u9009\u62e9\u65f6\uff0c\u201c\u590d\u5236\u201d\u548c\u201c\u4fdd\u5b58\u4e3a\u201d\u662f\u9488\u5bf9\u6574\u4e2a\u56fe\u50cf\u7684\u3002\n\n\u6b64\u7a97\u53e3\u7684\u5feb\u6377\u952e\u5982\u4e0b\uff1a\n"CTRL+c" \u628a\u56fe\u50cf\u6216\u8005\u5b83\u88ab\u526a\u5207\u7684\u533a\u57df\u590d\u5236\u5230\u7cfb\u7edf\u7c98\u8d34\u677f\u3002\n"CTRL+s"\t \u628a\u56fe\u50cf\u6216\u8005\u5b83\u88ab\u526a\u5207\u7684\u533a\u57df\u4fdd\u5b58\u4e3a\u56fe\u50cf\u6587\u4ef6\u3002\n"CTRL+d / DELETE" \u5220\u9664\u6b64\u56fe\u50cf\u6587\u4ef6\u3002\n"CTRL+i" \u663e\u793a\u56fe\u50cf\u4fe1\u606f\u3002\n"CTRL+a" \u5168\u9009\u56fe\u50cf\u3002\n"PAGE DOWN" \u540c\u4e00\u76ee\u5f55\u4e0b\u7684\u4e0b\u4e00\u4e2a\u56fe\u50cf\u6587\u4ef6\u3002 \n"PAGE UP" \u540c\u4e00\u76ee\u5f55\u4e0b\u7684\u4e0a\u4e00\u4e2a\u56fe\u50cf\u6587\u4ef6\u3002 \n"CTRL+1" \u663e\u793a\u56fe\u50cf\u7684\u539f\u59cb\u5c3a\u5bf8\u3002\n"CTRL+2" \u628a\u56fe\u50cf\u7f29\u653e\u5230\u7a97\u53e3\u5c3a\u5bf8\u3002 \n"CTRL+3" \u653e\u5927\u56fe\u50cf\u3002 \n"CTRL+4" \u7f29\u5c0f\u56fe\u50cf\u3002\n"CTRL+m" \u663e\u793a/\u9690\u85cf\u6ce8\u91ca\uff08\u4e0d\u5f71\u54cd\u5c0f\u63d0\u793a\uff09 \n"CTRL+-" \u51cf\u5c0f\u5b57\u4f53\u5927\u5c0f\u3002\n"CTRL+=" \u589e\u52a0\u5b57\u4f53\u5927\u5c0f \u3002\n"F5" \u5173\u95ed\u6b64\u7a97\u53e3\u3002 +RecordingImages=\u5df2\u8bb0\u5f55{0}\u4e2a\u56fe\u50cf\u3002\u6b63\u5728\u7b49\u5f85\u65b0\u56fe\u50cf... +RecordImagesTips=\u70b9\u51fb\u201c\u5f00\u59cb\u201d\u4ee5\u540e\uff0c\u5de5\u5177\u5c06\u76d1\u89c6\u7cfb\u7edf\u7c98\u8d34\u677f\u4e2d\u7684\u56fe\u50cf\u5e76\u4fdd\u5b58/\u663e\u793a\u5b83\u4eec\u3002\n\n\u7cfb\u7edf\u7c98\u8d34\u677f\u4e2d\u7684\u56fe\u50cf\u6765\u81ea\uff1a\u622a\u5c4f\u3001\u6216\u8005\u8f6f\u4ef6\u4ea7\u751f\uff08\u5982\u201cCTRL+c\u201d\uff09\u3002\n\n\u5728Windows\u4e0a\uff0c\u622a\u5c4f\u7684\u5feb\u6377\u952e\uff1a\n"PrintScreen" \u5168\u5c4f\u622a\u56fe\u3002\n"Alt+PrintScreen" \u5bf9\u5f53\u524d\u6d3b\u8dc3\u7a97\u53e3\u622a\u5c4f\u3002\n\n\u5728Linux\u4e0a\uff0c\u622a\u5c4f\u7684\u5feb\u6377\u952e\uff1a\n"Ctrl+PrintScreen" \u5168\u5c4f\u622a\u56fe\u3002\n"Ctrl+Alt+PrintScreen" \u5bf9\u5f53\u524d\u6d3b\u8dc3\u7a97\u53e3\u622a\u5c4f\u3002\n"Shift+Ctrl+PrintScreen" \u5bf9\u9009\u62e9\u7684\u533a\u57df\u622a\u5c4f\u3002\n\n\u5728Mac\u4e0a\uff0c\u622a\u5c4f\u7684\u5feb\u6377\u952e\uff1a\n"Command+Control+Shift+3" \u5168\u5c4f\u622a\u56fe\u3002\n"Command+Control+Shift+4" \u5bf9\u9009\u62e9\u7684\u533a\u57df\u622a\u5c4f\u3002\n"Command+Control+Shift+4+Spacebar" \u5bf9\u5f53\u524d\u6d3b\u8dc3\u7a97\u53e3\u622a\u5c4f\u3002\n +RecordImagesInSystemClipBoard=\u8bb0\u5f55\u7cfb\u7edf\u7c98\u8d34\u677f\u4e2d\u7684\u56fe\u50cf +DirectoryReserved=\u8fd9\u662fMyBox\u7684\u4fdd\u7559\u76ee\u5f55\u3002 +ImagesBrowser=\u6d4f\u89c8\u56fe\u50cf +Manufacture=\u5904\u7406 +PdfViewTips=\u5f53\u201c\u526a\u5207\u201d\u88ab\u9009\u62e9\u65f6,\u201c\u590d\u5236\u201d\u548c\u201c\u4fdd\u5b58\u4e3a\u201d\u662f\u9488\u5bf9\u88ab\u9009\u62e9\u533a\u57df\u7684\u3002\n\u9009\u62e9\u533a\u57df\uff1a\u5de6\u952e\u70b9\u51fb\u56fe\u50cf\u4ee5\u53d6\u5de6\u4e0a\u89d2\uff0c\u53f3\u952e\u70b9\u51fb\u53d6\u53f3\u4e0b\u89d2\u3002\n\n\u5f53\u201c\u526a\u5207\u201d\u672a\u88ab\u9009\u62e9\u65f6\uff0c\u201c\u590d\u5236\u201d\u548c\u201c\u4fdd\u5b58\u4e3a\u201d\u662f\u9488\u5bf9\u6574\u4e2a\u56fe\u50cf\u7684\u3002\n\n\u6b64\u7a97\u53e3\u7684\u5feb\u6377\u952e\u5982\u4e0b\uff1a\n"CTRL+i" \u663e\u793a\u6587\u4ef6\u4fe1\u606f\u3002\n"CTRL+c" \u628a\u56fe\u50cf\u6216\u8005\u5b83\u88ab\u526a\u5207\u7684\u533a\u57df\u590d\u5236\u5230\u7cfb\u7edf\u7c98\u8d34\u677f\u3002\n"CTRL+s"\t \u628a\u56fe\u50cf\u6216\u8005\u5b83\u88ab\u526a\u5207\u7684\u533a\u57df\u4fdd\u5b58\u4e3a\u56fe\u50cf\u6587\u4ef6\u3002\n"CTRL+a" \u5168\u9009\u56fe\u50cf\u3002\n"PAGE DOWN" \u6b64\u6587\u4ef6\u7684\u4e0b\u4e00\u9875\u3002 \n"PAGE UP" \u6b64\u6587\u4ef6\u7684\u4e0a\u4e00\u9875\u3002 \n"HOME" \u6b64\u6587\u4ef6\u7684\u7b2c\u4e00\u9875\u3002 \n"END" \u6b64\u6587\u4ef6\u7684\u6700\u540e\u4e00\u9875\u3002 \n"CTRL+1" \u663e\u793a\u56fe\u50cf\u7684\u539f\u59cb\u5c3a\u5bf8\u3002\n"CTRL+2" \u628a\u56fe\u50cf\u7f29\u653e\u5230\u7a97\u53e3\u5c3a\u5bf8\u3002 \n"CTRL+3" \u653e\u5927\u56fe\u50cf\u3002 \n"CTRL+4" \u7f29\u5c0f\u56fe\u50cf\u3002\n"CTRL+m" \u663e\u793a/\u9690\u85cf\u6ce8\u91ca\uff08\u4e0d\u5f71\u54cd\u5c0f\u63d0\u793a\uff09 \n"CTRL+-" \u51cf\u5c0f\u5b57\u4f53\u5927\u5c0f\n"CTRL+=" \u589e\u52a0\u5b57\u4f53\u5927\u5c0f\n"F5" \u5173\u95ed\u6b64\u7a97\u53e3\u3002 +ImageBrowserTips=\u70b9\u51fb\u4e00\u4e2a\u56fe\u7247\u4ee5\u9009\u62e9\u5b83\uff0c\u518d\u6b21\u70b9\u51fb\u4ee5\u53d6\u6d88\u9009\u62e9\u3002\n\u53cc\u51fb\u56fe\u7247\u4ee5\u5728\u65b0\u7a97\u53e3\u4e2d\u67e5\u770b\u5b83\u3002\n\n\u5f53\u56fe\u7247\u88ab\u9009\u62e9\u65f6\uff0c\u7f29\u653e/\u65cb\u8f6c/\u79fb\u52a8/\u5220\u9664\u662f\u9488\u5bf9\u88ab\u9009\u62e9\u7684\u56fe\u7247\u3002\n\u5f53\u53ea\u6709\u4e00\u4e2a\u56fe\u7247\u88ab\u9009\u62e9\u65f6\uff0c\u53ef\u4ee5\u6267\u884c\u67e5\u770b/\u4fe1\u606f/\u91cd\u547d\u540d\u3002\n\u5f53\u6ca1\u6709\u56fe\u7247\u88ab\u9009\u62e9\u65f6\uff0c\u7f29\u653e/\u65cb\u8f6c/\u79fb\u52a8\u662f\u9488\u5bf9\u5f53\u524d\u7a97\u53e3\u4e2d\u6240\u6709\u56fe\u7247\u3002\n\n\u6b64\u7a97\u53e3\u7684\u5feb\u6377\u952e\u5982\u4e0b\uff1a\n"CTRL+1" \u663e\u793a\u56fe\u50cf\u7684\u539f\u59cb\u5c3a\u5bf8\u3002\n"CTRL+2" \u628a\u56fe\u50cf\u7f29\u653e\u5230\u7a97\u53e3\u5c3a\u5bf8\u3002 \n"CTRL+3" \u653e\u5927\u56fe\u50cf\u3002 \n"CTRL+4" \u7f29\u5c0f\u56fe\u50cf\u3002\n"CTRL+i" \u663e\u793a\u88ab\u9009\u62e9\u56fe\u50cf\u7684\u4fe1\u606f\u3002\n"CTRL+d / DELETE" \u5220\u9664\u88ab\u9009\u62e9\u7684\u56fe\u50cf\u6587\u4ef6\u3002\n"PAGE DOWN" \u540c\u4e00\u76ee\u5f55\u4e0b\u7684\u4e0b\u4e00\u6279\u56fe\u50cf\u6587\u4ef6\u3002 \n"PAGE UP" \u540c\u4e00\u76ee\u5f55\u4e0b\u7684\u4e0a\u4e00\u6279\u56fe\u50cf\u6587\u4ef6\u3002 \n"CTRL+m" \u663e\u793a/\u9690\u85cf\u6ce8\u91ca\uff08\u4e0d\u5f71\u54cd\u5c0f\u63d0\u793a\uff09 \n"CTRL+-" \u51cf\u5c0f\u5b57\u4f53\u5927\u5c0f\u3002\n"CTRL+=" \u589e\u52a0\u5b57\u4f53\u5927\u5c0f \u3002\n"F5" \u5173\u95ed\u6b64\u7a97\u53e3\u3002 +BytesEditerTips=\u6bcf\u4e2a\u5b57\u8282\u88ab\u8868\u793a\u4e3a\u5341\u516d\u8fdb\u5236\u7684\u4e24\u4e2a\u5b57\u7b26, \u598205, A1, EF\u3002\u6240\u6709\u7684\u7a7a\u683c\u3001\u6362\u884c\u3001\u548c\u975e\u6cd5\u6570\u503c\u90fd\u88ab\u5ffd\u7565\u3002\n\u6362\u884c\u7b26\u53ea\u7528\u4e8e\u663e\u793a\uff0c\u65e0\u5b9e\u9645\u5f71\u54cd\u3002\n\n\u5f53"\u6587\u5b57"\u9875\u7b7e\u4e0b\u7684\u201c\u89e3\u7801\u201d\u88ab\u9009\u62e9\u65f6\uff0c\u5b57\u8282\u6309\u9009\u62e9\u7684\u5b57\u7b26\u96c6\u88ab\u89e3\u7801\u3002\u5b57\u7b26\u96c6\u3001\u6362\u884c\u7b26\u3001\u548c\u5206\u9875\u90fd\u4f1a\u5f71\u54cd\u5b57\u8282\u7684\u7f16\u7801\u3002\n\u89e3\u7801\u540e\u7684\u6587\u672c\u663e\u793a\u5728\u53f3\u8fb9\uff0c\u53ef\u4ee5\u4e0e\u5de6\u8fb9\u7684\u5b57\u8282\u540c\u6b65\u6eda\u52a8\u3002\n\u5f53\u5728\u5de6\u8fb9\u9009\u62e9\u5b57\u8282\u65f6\uff0c\u76f8\u5e94\u7684\u89e3\u7801\u6587\u672c\u5728\u53f3\u8fb9\u88ab\u9ad8\u4eae\u3002\n\n\u5f53\u9875\u9762\u4e0a\u7684\u5b57\u8282\u88ab\u4fee\u6539\u65f6\uff0c\u5728\u4fdd\u5b58\u66f4\u6539\u4e4b\u524d\u90e8\u5206\u529f\u80fd\u5c06\u4e0d\u53ef\u7528\u3002\n\n\u6b64\u7a97\u53e3\u7684\u5feb\u6377\u952e\u5982\u4e0b\uff1a\n"CTRL+c" \u5c06\u9009\u62e9\u7684\u5b57\u8282\u590d\u5236\u5230\u7cfb\u7edf\u7c98\u8d34\u677f\u3002\n"CTRL+v" \u7c98\u8d34\u7cfb\u7edf\u7c98\u8d34\u677f\u7684\u5b57\u4e32\u3002\n"CTRL+x" \u526a\u5207\u88ab\u9009\u62e9\u7684\u5b57\u8282\u5e76\u590d\u5236\u5230\u7cfb\u7edf\u7c98\u8d34\u677f\u3002\n"CTRL+d / DELETE" \u5220\u9664\u88ab\u9009\u62e9\u7684\u5b57\u8282\u3002\n"CTRL+a" \u9009\u62e9\u672c\u9875\u6240\u6709\u7684\u5b57\u8282\u3002\n"CTRL+s"\t \u4fdd\u5b58\u66f4\u6539\u3002\n"CTRL+z" \u64a4\u9500\u4e0a\u4e00\u4e2a\u4fee\u6539\u3002\n"CTRL+y" \u91cd\u505a\u4e0a\u4e00\u4e2a\u4fee\u6539\u3002\n"CTRL+r" \u653e\u5f03\u6240\u6709\u672a\u4fdd\u5b58\u7684\u4fee\u6539\uff0c\u6062\u590d\u672c\u9875\u7684\u5b57\u8282\u3002\n"CTRL+f"\t \u53d1\u73b0\u7b2c\u4e00\u4e2a\u3002\uff08\u5728\u53d1\u73b0/\u66ff\u6362\u9875\u7b7e\u4e0b\uff09\n"CTRL+l" \u53d1\u73b0\u6700\u540e\u4e00\u4e2a\u3002\uff08\u5728\u53d1\u73b0/\u66ff\u6362\u9875\u7b7e\u4e0b\uff09\n"CTRL+n" \u53d1\u73b0\u4e0b\u4e00\u4e2a\u3002\uff08\u5728\u53d1\u73b0/\u66ff\u6362\u9875\u7b7e\u4e0b\uff09\n"CTRL+p" \u53d1\u73b0\u4e0a\u4e00\u4e2a\u3002\uff08\u5728\u53d1\u73b0/\u66ff\u6362\u9875\u7b7e\u4e0b\uff09\n"CTRL+e" \u66ff\u6362\u3002\uff08\u5728\u53d1\u73b0/\u66ff\u6362\u9875\u7b7e\u4e0b\uff09\n"PAGE DOWN" \u672c\u6587\u4ef6\u7684\u4e0b\u4e00\u9875\u3002 \n"PAGE UP" \u672c\u6587\u4ef6\u7684\u4e0a\u4e00\u9875\u3002 \n"HOME" \u672c\u6587\u4ef6\u7684\u7b2c\u4e00\u9875\u3002 \n"END" \u672c\u6587\u4ef6\u7684\u6700\u540e\u4e00\u9875\u3002 \n"CTRL+m" \u663e\u793a/\u9690\u85cf\u6ce8\u91ca\uff08\u4e0d\u5f71\u54cd\u5c0f\u63d0\u793a\uff09\u3002\n"CTRL+-" \u51cf\u5c0f\u5b57\u4f53\u5927\u5c0f\u3002\n"CTRL+=" \u589e\u52a0\u5b57\u4f53\u5927\u5c0f \u3002\n"F5" \u5173\u95ed\u6b64\u7a97\u53e3\u3002 +TextEditerTips=\u53ef\u4ee5\u4fee\u6539\u5b57\u7b26\u96c6\u548c\u6362\u884c\u7b26\uff0c\u5728\u4fdd\u5b58\u6587\u4ef6\u65f6\u751f\u6548\u3002\n\n\u5f53"\u5b57\u8282"\u9875\u7b7e\u4e0b\u7684\u201c\u663e\u793a\u5341\u516d\u8fdb\u5236\u201d\u88ab\u9009\u62e9\u65f6\uff0c\u6587\u672c\u6309\u5f53\u524d\u5b57\u7b26\u96c6\u88ab\u7f16\u7801\u3002\n\u7f16\u7801\u540e\u7684\u5b57\u8282\u663e\u793a\u5728\u53f3\u8fb9\uff0c\u53ef\u4ee5\u4e0e\u5de6\u8fb9\u7684\u6587\u672c\u540c\u6b65\u6eda\u52a8\u3002\n\u5f53\u5728\u5de6\u8fb9\u9009\u62e9\u6587\u672c\u65f6\uff0c\u76f8\u5e94\u7684\u7f16\u7801\u5b57\u8282\u5728\u53f3\u8fb9\u88ab\u9ad8\u4eae\u3002\n\n\u5f53\u9875\u9762\u4e0a\u7684\u6587\u672c\u88ab\u4fee\u6539\u65f6\uff0c\u5728\u4fdd\u5b58\u66f4\u6539\u4e4b\u524d\u90e8\u5206\u529f\u80fd\u5c06\u4e0d\u53ef\u7528\u3002\n\n\u6b64\u7a97\u53e3\u7684\u5feb\u6377\u952e\u5982\u4e0b\uff1a\n"CTRL+c" \u5c06\u9009\u62e9\u7684\u6587\u672c\u590d\u5236\u5230\u7cfb\u7edf\u7c98\u8d34\u677f\u3002\n"CTRL+v" \u7c98\u8d34\u7cfb\u7edf\u7c98\u8d34\u677f\u7684\u5b57\u4e32\u3002\n"CTRL+x" \u526a\u5207\u88ab\u9009\u62e9\u7684\u6587\u672c\u5e76\u590d\u5236\u5230\u7cfb\u7edf\u7c98\u8d34\u677f\u3002\n"CTRL+d / DELETE" \u5220\u9664\u88ab\u9009\u62e9\u7684\u6587\u672c\u3002\n"CTRL+a" \u9009\u62e9\u672c\u9875\u6240\u6709\u7684\u6587\u672c\u3002\n"CTRL+s"\t \u4fdd\u5b58\u66f4\u6539\u3002\n"CTRL+z" \u64a4\u9500\u4e0a\u4e00\u4e2a\u4fee\u6539\u3002\n"CTRL+y" \u91cd\u505a\u4e0a\u4e00\u4e2a\u4fee\u6539\u3002\n"CTRL+r" \u653e\u5f03\u6240\u6709\u672a\u4fdd\u5b58\u7684\u4fee\u6539\uff0c\u6062\u590d\u672c\u9875\u7684\u6587\u672c\u3002\n"CTRL+f"\t \u53d1\u73b0\u7b2c\u4e00\u4e2a\u3002\uff08\u5728\u53d1\u73b0/\u66ff\u6362\u9875\u7b7e\u4e0b\uff09\n"CTRL+l" \u53d1\u73b0\u6700\u540e\u4e00\u4e2a\u3002\uff08\u5728\u53d1\u73b0/\u66ff\u6362\u9875\u7b7e\u4e0b\uff09\n"CTRL+n" \u53d1\u73b0\u4e0b\u4e00\u4e2a\u3002\uff08\u5728\u53d1\u73b0/\u66ff\u6362\u9875\u7b7e\u4e0b\uff09\n"CTRL+p" \u53d1\u73b0\u4e0a\u4e00\u4e2a\u3002\uff08\u5728\u53d1\u73b0/\u66ff\u6362\u9875\u7b7e\u4e0b\uff09\n"CTRL+e" \u66ff\u6362\u3002\uff08\u5728\u53d1\u73b0/\u66ff\u6362\u9875\u7b7e\u4e0b\uff09\n"PAGE DOWN" \u672c\u6587\u4ef6\u7684\u4e0b\u4e00\u9875\u3002 \n"PAGE UP" \u672c\u6587\u4ef6\u7684\u4e0a\u4e00\u9875\u3002 \n"HOME" \u672c\u6587\u4ef6\u7684\u7b2c\u4e00\u9875\u3002 \n"END" \u672c\u6587\u4ef6\u7684\u6700\u540e\u4e00\u9875\u3002 \n"CTRL+m" \u663e\u793a/\u9690\u85cf\u6ce8\u91ca\uff08\u4e0d\u5f71\u54cd\u5c0f\u63d0\u793a\uff09 \n"CTRL+-" \u51cf\u5c0f\u5b57\u4f53\u5927\u5c0f\u3002\n"CTRL+=" \u589e\u52a0\u5b57\u4f53\u5927\u5c0f \u3002\n"F5" \u5173\u95ed\u6b64\u7a97\u53e3\u3002 +WhenNewImageInSystemBoard=\u5f53\u7cfb\u7edf\u7c98\u8d34\u677f\u4e2d\u51fa\u73b0\u65b0\u56fe\u50cf +SaveAndView=\u4fdd\u5b58\u5e76\u67e5\u770b +RecordOptions=\u8bb0\u5f55\u9009\u9879 +ImageCalculation=\u8ba1\u7b97\u56fe\u50cf +GreyHistogram=\u7070\u5ea6\u76f4\u65b9\u56fe +RedHistogram=\u7ea2\u8272\u76f4\u65b9\u56fe +GreenHistogram=\u7eff\u8272\u76f4\u65b9\u56fe +BlueHistogram=\u84dd\u8272\u76f4\u65b9\u56fe +OpacityHistogram=\u4e0d\u900f\u660e\u5ea6\u76f4\u65b9\u56fe +HueHistogram=\u8272\u76f8\u76f4\u65b9\u56fe +SaturationHistogram=\u9971\u548c\u5ea6\u76f4\u65b9\u56fe +BrightnessHistogram=\u4eae\u5ea6\u76f4\u65b9\u56fe +Histogram=\u76f4\u65b9\u56fe +Data=\u6570\u636e +PixelsNumber=\u50cf\u7d20\u4e2a\u6570 +DataType=\u6570\u636e\u7c7b\u578b +Greyscale=\u7070\u5ea6 +GreyValue=\u7070\u5ea6\u503c +ImageStatistic=\u56fe\u50cf\u7edf\u8ba1 +StatisticValue=\u7edf\u8ba1\u503c +OccurrenceNumber=\u51fa\u73b0\u6b21\u6570 +Median=\u4e2d\u4f4d\u6570 +Statistic=\u7edf\u8ba1 +Percentage=\u767e\u5206\u6bd4 +Sum=\u603b\u548c +Showcase=\u5c55\u793a +Sequence=\u5e8f\u53f7 +OrderSequence=\u6392\u5e8f\u53f7 +HueGrades=\u8272\u76f8\u5206\u7ea7 +BrightnessGrades=\u660e\u4eae\u5ea6\u5206\u7ea7 +SaturationGrades=\u9971\u548c\u5ea6\u5206\u7ea7 +DataNumber=\u6570\u636e\u6570 +Algorithm=\u7b97\u6cd5 +Palette=\u4e3b\u8272 +Division=\u9664\u6cd5 +Mod=\u6c42\u4f59 +MedianCut=\u4e8c\u5206\u6cd5 +kMeansClustering=k-\u5747\u503c\u805a\u7c7b +ColorsNumber=\u989c\u8272\u6570\u91cf +RGBUniformQuantization=RGB\u5747\u7b49\u91cf\u5316 +HSBUniformQuantization=HSB\u5747\u7b49\u91cf\u5316 +ColorHistogram=\u989c\u8272\u76f4\u65b9\u56fe +ColorPie=\u989c\u8272\u997c\u56fe +ColorQuantization=\u989c\u8272\u91cf\u5316 +Mode=\u4f17\u6570 +CategoryNumber=\u5206\u7c7b\u6570 +Dithering=\u6296\u52a8\u5904\u7406 +QuantizationComments=\u51cf\u5c11\u56fe\u50cf\u4e2d\u989c\u8272\u6570\u91cf\u7684\u6280\u672f\u79f0\u4e3a\u201c\u989c\u8272\u91cf\u5316\u201d\u3002\n\u201c\u6296\u52a8\u5904\u7406\u201d\u53ef\u4ee5\u6539\u5584\u989c\u8272\u91cf\u5316\u540e\u7684\u56fe\u50cf\u7684\u8d28\u91cf\uff0c\u53ea\u80fd\u7528\u4e8e\u5168\u56fe\u3002 +Variance=\u65b9\u5dee +Skewness=\u659c\u5ea6 +Mean=\u5747\u503c +ColorFeatures=\u989c\u8272\u7279\u5f81 +BWThresholdComments=\u9608\u503c\u4e3a0~255\uff0c\u53ef\u4ee5\u7a7a\u767d\u4ee5\u53d6\u7f3a\u7701\u503c\u3002\n\u6296\u52a8\u5904\u7406\u53ea\u80fd\u7528\u4e8e\u5168\u56fe\u3002 +Pop=\u5f39\u51fa +Ref=\u53c2\u8003 +BOMcomments=BOM(Byte Order Marks) \u662f\u6587\u4ef6\u5934\u76842\u62163\u4e2a\u5b57\u8282\uff0c\u7528\u4e8eUTF-16\u6216UTF-32\u3002\n\u4e00\u4e9bWindows\u7a0b\u5e8f\u4f1a\u5728UTF-8\u6587\u4ef6\u5934\u4e5f\u5199\u4e0aBOM\uff0c\u5176\u53ef\u80fd\u5bfc\u81f4\u5728\u522b\u7684\u5e73\u53f0\u8bfb\u5199\u9519\u8bef\u3002 +FontSize12=\u5b57\u4f53\u5927\u5c0f 12px +FontSize15=\u5b57\u4f53\u5927\u5c0f 15px +FontSize17=\u5b57\u4f53\u5927\u5c0f 17px +DitherComments=\u6296\u52a8\u5904\u7406\u662f\u6269\u6563\u91cf\u5316\u8bef\u5dee\u4ee5\u907f\u514d\u8272\u5e26\u7684\u6280\u672f\u3002\n\u5728\u989c\u8272\u91cf\u5316\uff08\u51cf\u8272\uff09\u4ee5\u540e\uff0c\u5229\u7528\u5b83\u53ef\u4ee5\u6539\u5584\u56fe\u50cf\u8d28\u91cf\u3002 +Contrast=\u5bf9\u6bd4\u5ea6 +HistogramEqualization=\u76f4\u65b9\u56fe\u5747\u8861\u5316 +SampleSize=\u6837\u672c\u5927\u5c0f +HSBHistogramEqualization=HSB\u76f4\u65b9\u56fe\u5747\u8861 +GrayHistogramEqualization=\u7070\u5ea6\u76f4\u65b9\u56fe\u5747\u8861 +AdaptiveHistogramEqualization=\u81ea\u9002\u5e94\u76f4\u65b9\u56fe\u5747\u8861 +GrayHistogramShifting=\u7070\u5ea6\u76f4\u65b9\u56fe\u4f4d\u79fb +Offset=\u504f\u79fb +LumaHistogramEqualization=\u4eae\u5ea6\u76f4\u65b9\u56fe\u5747\u8861 +GrayHistogramStretching=\u7070\u5ea6\u76f4\u65b9\u56fe\u62c9\u4f38 +LeftThreshold=\u5de6\u9608\u503c +RightThreshold=\u53f3\u9608\u503c +ColorMoments=Color Moments +Grey=\u7070\u8272 diff --git a/MyBox/src/main/resources/docs/mybox.css b/MyBox/src/main/resources/docs/mybox.css new file mode 100644 index 000000000..1c70a804d --- /dev/null +++ b/MyBox/src/main/resources/docs/mybox.css @@ -0,0 +1,37 @@ +/** + * @Author Mara + * @CreateDate 2019-2-3 14:21:36 + * @Version 1.0 + * @Description + * @License Apache License Version 2.0 + */ +body {font-size:14px; + /* + font-family: + -apple-system, BlinkMacSystemFont, + "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", + "Helvetica Neue", sans-serif; + */ +} +p.p1 {text-indent: 0em; font-size:17px;font-weight:bold; color:darkgreen} +p.p2 {text-indent: 0em; font-size:15px;font-weight:bold} +p.p3 {text-indent: 0em; font-size:14px;font-weight:bold} +.article {width: 100%; margin:0 auto;font-size:14px;font-weight:normal;} +.paragraph {text-indent: 2em; font-size:14px;} +.link {text-indent: 6em; font-size:14px;} +.command {text-indent: 6em; font-size:14px; color:darkblue} +.pix {text-indent: 6em; } +.refer {text-indent: 6em; font-size:14px; color:darkblue} +ol.inside {list-style-position: inside; text-indent: 2em;} +.description {font-size:14px; padding: 5px; background-color:#336633; font-weight:bord; color: white} +.codes {font-size:14px; padding: 5px; background-color:black; font-weight:normal; color: #CCFF99} +.table1 {font-size:14px; width:90%; border-collapse:collapse; border:solid 1px;} +tr {border:solid#000 1px;} +td {border:solid#000 1px; } +.Header { font-weight:bold; text-align:center;} +.Data {font-weight:normal; text-align:left; } +ul.inside {list-style-position: inside; text-indent: 2em;} +.nav {text-indent: 2em; font-size:14px;font-weight:bold} +.menu {margin:0 auto;font-size:14px;font-weight:normal;} + + diff --git a/MyBox/src/main/resources/docs/mybox_help_main_en.html b/MyBox/src/main/resources/docs/mybox_help_main_en.html index a23acbde6..4a95d85ac 100644 --- a/MyBox/src/main/resources/docs/mybox_help_main_en.html +++ b/MyBox/src/main/resources/docs/mybox_help_main_en.html @@ -2,34 +2,7 @@ MyBox Helps - + @@ -67,6 +40,8 @@

MyBox

+ diff --git a/MyBox/src/main/resources/docs/mybox_help_main_zh.html b/MyBox/src/main/resources/docs/mybox_help_main_zh.html index 4b3d9a3ad..a6e2431da 100644 --- a/MyBox/src/main/resources/docs/mybox_help_main_zh.html +++ b/MyBox/src/main/resources/docs/mybox_help_main_zh.html @@ -2,34 +2,7 @@ MyBox帮助 - + @@ -67,6 +40,8 @@

MyBox

+ diff --git a/MyBox/src/main/resources/docs/mybox_help_nav_en.html b/MyBox/src/main/resources/docs/mybox_help_nav_en.html index 1a328076c..3e89f29ce 100644 --- a/MyBox/src/main/resources/docs/mybox_help_nav_en.html +++ b/MyBox/src/main/resources/docs/mybox_help_nav_en.html @@ -3,35 +3,7 @@ MyBox Helps - - + diff --git a/MyBox/src/main/resources/docs/mybox_help_nav_zh.html b/MyBox/src/main/resources/docs/mybox_help_nav_zh.html index 3ca8a10c7..255a69f2e 100644 --- a/MyBox/src/main/resources/docs/mybox_help_nav_zh.html +++ b/MyBox/src/main/resources/docs/mybox_help_nav_zh.html @@ -3,35 +3,7 @@ MyBox帮助 - - + diff --git a/MyBox/src/main/resources/fxml/AlarmClock.fxml b/MyBox/src/main/resources/fxml/AlarmClock.fxml index 698b9cfcd..325a29620 100644 --- a/MyBox/src/main/resources/fxml/AlarmClock.fxml +++ b/MyBox/src/main/resources/fxml/AlarmClock.fxml @@ -135,13 +135,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - - - - - - + + + + + + + + @@ -176,7 +177,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - +