diff --git a/ImageConverter/.idea/workspace.xml b/ImageConverter/.idea/workspace.xml
index fa57ff44..fe2e85d6 100644
--- a/ImageConverter/.idea/workspace.xml
+++ b/ImageConverter/.idea/workspace.xml
@@ -63,11 +63,11 @@
-
+
-
-
+
+
@@ -75,39 +75,29 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
@@ -119,7 +109,6 @@
- Недопус
нед
размер
open
@@ -149,6 +138,7 @@
hints
OCIF
loadImage(
+ onDithering
sample
@@ -168,18 +158,18 @@
@@ -208,9 +198,6 @@
-
-
-
@@ -247,6 +234,9 @@
+
+
+
@@ -269,6 +259,7 @@
+
@@ -529,16 +520,17 @@
-
+
-
+
-
+
+
@@ -564,7 +556,6 @@
-
@@ -586,30 +577,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -623,7 +590,7 @@
-
+
@@ -636,15 +603,15 @@
+
+
+
-
-
-
@@ -683,7 +650,7 @@
-
+
@@ -703,15 +670,15 @@
+
+
+
-
-
-
@@ -743,7 +710,7 @@
-
+
@@ -788,15 +755,15 @@
+
+
+
-
-
-
@@ -824,22 +791,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -862,13 +813,6 @@
-
-
-
-
-
-
-
@@ -895,10 +839,61 @@
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -911,35 +906,32 @@
-
+
-
-
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
diff --git a/ImageConverter/out/artifacts/ImageConverter_jar/ImageConverter.jar b/ImageConverter/out/artifacts/ImageConverter_jar/ImageConverter.jar
index 078987df..6841842a 100644
Binary files a/ImageConverter/out/artifacts/ImageConverter_jar/ImageConverter.jar and b/ImageConverter/out/artifacts/ImageConverter_jar/ImageConverter.jar differ
diff --git a/ImageConverter/out/production/ImageConverter/sample/Color.class b/ImageConverter/out/production/ImageConverter/sample/Color.class
index de25cb92..d388ea02 100644
Binary files a/ImageConverter/out/production/ImageConverter/sample/Color.class and b/ImageConverter/out/production/ImageConverter/sample/Color.class differ
diff --git a/ImageConverter/out/production/ImageConverter/sample/Image.class b/ImageConverter/out/production/ImageConverter/sample/Image.class
index bccb2428..572a9599 100644
Binary files a/ImageConverter/out/production/ImageConverter/sample/Image.class and b/ImageConverter/out/production/ImageConverter/sample/Image.class differ
diff --git a/ImageConverter/out/production/ImageConverter/sample/ImageConverter.fxml b/ImageConverter/out/production/ImageConverter/sample/ImageConverter.fxml
index ced45ef7..2258d952 100644
--- a/ImageConverter/out/production/ImageConverter/sample/ImageConverter.fxml
+++ b/ImageConverter/out/production/ImageConverter/sample/ImageConverter.fxml
@@ -13,7 +13,7 @@
-
+
@@ -23,7 +23,7 @@
-
+
@@ -33,7 +33,7 @@
-
+
@@ -99,60 +99,60 @@
-
+
-
+
-
-
+
diff --git a/ImageConverter/out/production/ImageConverter/sample/Main$1.class b/ImageConverter/out/production/ImageConverter/sample/Main$1.class
index 1b63caa2..c03674c4 100644
Binary files a/ImageConverter/out/production/ImageConverter/sample/Main$1.class and b/ImageConverter/out/production/ImageConverter/sample/Main$1.class differ
diff --git a/ImageConverter/out/production/ImageConverter/sample/Main$2$1.class b/ImageConverter/out/production/ImageConverter/sample/Main$2$1.class
index 0f9defd7..f70233b8 100644
Binary files a/ImageConverter/out/production/ImageConverter/sample/Main$2$1.class and b/ImageConverter/out/production/ImageConverter/sample/Main$2$1.class differ
diff --git a/ImageConverter/out/production/ImageConverter/sample/Main$2.class b/ImageConverter/out/production/ImageConverter/sample/Main$2.class
index ffd9851f..966fcecc 100644
Binary files a/ImageConverter/out/production/ImageConverter/sample/Main$2.class and b/ImageConverter/out/production/ImageConverter/sample/Main$2.class differ
diff --git a/ImageConverter/out/production/ImageConverter/sample/Main.class b/ImageConverter/out/production/ImageConverter/sample/Main.class
index 93a94638..6b34e38e 100644
Binary files a/ImageConverter/out/production/ImageConverter/sample/Main.class and b/ImageConverter/out/production/ImageConverter/sample/Main.class differ
diff --git a/ImageConverter/out/production/ImageConverter/sample/OCIF.class b/ImageConverter/out/production/ImageConverter/sample/OCIF.class
index 9bdddb60..d7ef5c69 100644
Binary files a/ImageConverter/out/production/ImageConverter/sample/OCIF.class and b/ImageConverter/out/production/ImageConverter/sample/OCIF.class differ
diff --git a/ImageConverter/src/sample/Color.java b/ImageConverter/src/sample/Color.java
index b9007774..eb943d08 100644
--- a/ImageConverter/src/sample/Color.java
+++ b/ImageConverter/src/sample/Color.java
@@ -38,11 +38,25 @@ public class Color {
public static Color sum(Color color1, Color color2)
{
+ int aSum = color1.alpha + color2.alpha;
+ int rSum = color1.red + color2.red;
+ int gSum = color1.green + color2.green;
+ int bSum = color1.blue + color2.blue;
+
+ if (aSum > 255) aSum = 255;
+ if (rSum > 255) rSum = 255;
+ if (gSum > 255) gSum = 255;
+ if (bSum > 255) bSum = 255;
+
+ return new Color(aSum, rSum, gSum, bSum);
+ }
+
+ public static Color average(Color color1, Color color2) {
return new Color(
- color1.alpha + color2.alpha,
- color1.red + color2.red,
- color1.green + color2.green,
- color1.blue + color2.blue
+ (color1.alpha + color2.alpha) / 2,
+ (color1.red + color2.red) / 2,
+ (color1.green + color2.green) / 2,
+ (color1.blue + color2.blue) / 2
);
}
diff --git a/ImageConverter/src/sample/Image.java b/ImageConverter/src/sample/Image.java
index 65734aa7..ca6d5e5f 100644
--- a/ImageConverter/src/sample/Image.java
+++ b/ImageConverter/src/sample/Image.java
@@ -96,6 +96,11 @@ public class Image {
return new Pixel(minColor, maxColor, 0x00, brailleChar);
}
+ private static final double Xp1Yp0 = 7.0d / 16.0d;
+ private static final double Xp1Yp1 = 1.0d / 16.0d;
+ private static final double Xp0Yp1 = 5.0d / 16.0d;
+ private static final double Xm1Y1 = 3.0d / 16.0d;
+
static Image dither(Image image, double intensity) {
for (int y = 0; y < image.height; y++) {
for (int x = 0; x < image.width; x++) {
@@ -108,13 +113,13 @@ public class Image {
if (x < image.width - 1) {
image.pixels[y][x + 1] = Color.sum(
image.pixels[y][x + 1],
- Color.multiply(colorDifference, 7.0d / 16.0d * intensity / 100.0d)
+ Color.multiply(colorDifference, Xp1Yp0 * intensity)
);
if (y < image.height - 1) {
image.pixels[y + 1][x + 1] = Color.sum(
image.pixels[y + 1][x + 1],
- Color.multiply(colorDifference, 1.0d / 16.0d * intensity / 100.0d)
+ Color.multiply(colorDifference, Xp1Yp1 * intensity)
);
}
}
@@ -122,13 +127,13 @@ public class Image {
if (y < image.height - 1) {
image.pixels[y + 1][x] = Color.sum(
image.pixels[y + 1][x],
- Color.multiply(colorDifference, 5.0d / 16.0d * intensity / 100.0d)
+ Color.multiply(colorDifference, Xp0Yp1 * intensity)
);
if (x > 0) {
image.pixels[y + 1][x - 1] = Color.sum(
image.pixels[y + 1][x - 1],
- Color.multiply(colorDifference, 3.0d / 16.0d * intensity / 100.0d)
+ Color.multiply(colorDifference, Xm1Y1 * intensity)
);
}
}
@@ -138,6 +143,7 @@ public class Image {
return image;
}
+
static Pixel getSemiPixel(Image image, int x, int y) {
Color upper = image.pixels[y][x], lower = new Color(0xFF, 0x0, 0x0, 0x0);
diff --git a/ImageConverter/src/sample/ImageConverter.fxml b/ImageConverter/src/sample/ImageConverter.fxml
index ced45ef7..2258d952 100644
--- a/ImageConverter/src/sample/ImageConverter.fxml
+++ b/ImageConverter/src/sample/ImageConverter.fxml
@@ -13,7 +13,7 @@
-
+
@@ -23,7 +23,7 @@
-
+
@@ -33,7 +33,7 @@
-
+
@@ -99,60 +99,60 @@
-
+
-
+
-
+
-
-
-
+
+
+
-
-
-
-
-
+
-
-
-
+
+
+
-
+
+
+
+
+
+
+
+
+
-
+
-
+
@@ -160,32 +160,53 @@
-
+
-
+
-
+
-
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
diff --git a/ImageConverter/src/sample/Main.java b/ImageConverter/src/sample/Main.java
index 93e8e54b..61fe6283 100644
--- a/ImageConverter/src/sample/Main.java
+++ b/ImageConverter/src/sample/Main.java
@@ -4,6 +4,8 @@ import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
@@ -15,6 +17,8 @@ import javafx.scene.control.TextField;
import javafx.scene.image.ImageView;
import javafx.scene.input.*;
import javafx.scene.layout.GridPane;
+import javafx.scene.layout.Pane;
+import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
@@ -29,6 +33,8 @@ import java.util.regex.Pattern;
public class Main extends Application {
+ public GridPane mainPane;
+
public CheckBox keepProportionsCheckBox;
public Button openButton;
public Button convertButton;
@@ -36,13 +42,10 @@ public class Main extends Application {
public TextField heightTextField;
public ImageView imageView;
public CheckBox brailleCheckBox;
- public CheckBox ditheringCheckBox;
public Label imageSizeInfoLabel;
- public Slider ditheringSlider;
public ComboBox encodingMethodComboBox;
public ImageView dragDropFilesImageView;
public GridPane settingsPane;
- public GridPane mainPane;
public GridPane hintsGridPane;
public GridPane dragImageGridPane;
@@ -51,6 +54,12 @@ public class Main extends Application {
public ImageView OCIFStringResultImageView;
public GridPane OCIFStringResultGridPane;
+ public CheckBox ditheringCheckBox;
+ public GridPane ditheringMainPane;
+ public Label ditheringOpacityLabel;
+ public Pane ditheringBackgroundPane;
+ public Slider ditheringOpacitySlider;
+
private String currentImagePath = "sample/Resources/Background.png";
@Override
@@ -184,7 +193,29 @@ public class Main extends Application {
}
public void onDitheringStateChanged() {
- ditheringSlider.setDisable(!ditheringCheckBox.isSelected());
+ boolean state = ditheringCheckBox.isSelected();
+
+ Timeline timeline = newTimeLine(
+ 150,
+ new KeyValue[] {
+ new KeyValue(ditheringBackgroundPane.opacityProperty(), state ? 0 : 1),
+ new KeyValue(ditheringMainPane.prefHeightProperty(), state ? 38 : 120),
+ new KeyValue(ditheringOpacitySlider.layoutYProperty(), state ? 38 : 65),
+ new KeyValue(ditheringOpacityLabel.layoutYProperty(), state ? 38 : 45)
+
+ },
+ new KeyValue[] {
+ new KeyValue(ditheringBackgroundPane.opacityProperty(), state ? 1 : 0),
+ new KeyValue(ditheringMainPane.prefHeightProperty(), state ? 120 : 38),
+ new KeyValue(ditheringOpacitySlider.layoutYProperty(), state ? 65 : 38),
+ new KeyValue(ditheringOpacityLabel.layoutYProperty(), state ? 45 : 38)
+ }
+ );
+
+ timeline.setOnFinished(event -> ditheringOpacitySlider.setDisable(!state));
+
+ timeline.play();
+
}
private boolean checkTextField(TextField textField) {
@@ -272,12 +303,12 @@ public class Main extends Application {
public void save() throws IOException {
if (encodingMethodComboBox.getValue().contains("OCIFString")) {
OCIFStringResultTextField.setText(OCIF.convertToString(
- currentImagePath,
- Integer.parseInt(widthTextField.getText()),
- Integer.parseInt(heightTextField.getText()),
- brailleCheckBox.isSelected(),
- ditheringCheckBox.isSelected(),
- ditheringSlider.getValue()
+ currentImagePath,
+ Integer.parseInt(widthTextField.getText()),
+ Integer.parseInt(heightTextField.getText()),
+ brailleCheckBox.isSelected(),
+ ditheringCheckBox.isSelected(),
+ ditheringOpacitySlider.getValue() / 100.0d
));
hintsGridPane.setVisible(true);
@@ -293,14 +324,14 @@ public class Main extends Application {
if (file != null) {
OCIF.convert(
- currentImagePath,
- file.getPath(),
- Integer.parseInt(widthTextField.getText()),
- Integer.parseInt(heightTextField.getText()),
- encodingMethodComboBox.getValue().contains("OCIF6") ? 6 : 5,
- brailleCheckBox.isSelected(),
- ditheringCheckBox.isSelected(),
- ditheringSlider.getValue()
+ currentImagePath,
+ file.getPath(),
+ Integer.parseInt(widthTextField.getText()),
+ Integer.parseInt(heightTextField.getText()),
+ encodingMethodComboBox.getValue().contains("OCIF6") ? 6 : 5,
+ brailleCheckBox.isSelected(),
+ ditheringCheckBox.isSelected(),
+ ditheringOpacitySlider.getValue() / 100.0d
);
}
}
diff --git a/ImageConverter/src/sample/OCIF.java b/ImageConverter/src/sample/OCIF.java
index 37d37f1e..00c3f0d3 100644
--- a/ImageConverter/src/sample/OCIF.java
+++ b/ImageConverter/src/sample/OCIF.java
@@ -80,7 +80,7 @@ class OCIF {
}
}
- private static sample.Image loadImage(String imagePath, int requestedWidth, int requestedHeight, boolean convertAsBraille, boolean enableDithering, double ditheringIntensity) {
+ private static sample.Image loadImage(String imagePath, int requestedWidth, int requestedHeight, boolean convertAsBraille, boolean enableDithering, double opacity) {
sample.Image image = new sample.Image(new javafx.scene.image.Image(imagePath,
requestedWidth * (convertAsBraille ? 2 : 1),
requestedHeight * (convertAsBraille ? 4 : 2),
@@ -89,7 +89,7 @@ class OCIF {
));
if (enableDithering) {
- image = sample.Image.dither(image, ditheringIntensity);
+ image = sample.Image.dither(image, opacity);
}
return image;
@@ -102,8 +102,8 @@ class OCIF {
result.append(pixel.symbol);
}
- static String convertToString(String imagePath, int requestedWidth, int requestedHeight, boolean convertAsBraille, boolean enableDithering, double ditheringIntensity) {
- sample.Image image = loadImage(imagePath, requestedWidth, requestedHeight, convertAsBraille, enableDithering, ditheringIntensity);
+ static String convertToString(String imagePath, int requestedWidth, int requestedHeight, boolean convertAsBraille, boolean enableDithering, double opacity) {
+ sample.Image image = loadImage(imagePath, requestedWidth, requestedHeight, convertAsBraille, enableDithering, opacity);
StringBuilder result = new StringBuilder();
result.append(String.format("%02X", requestedWidth));
@@ -127,8 +127,8 @@ class OCIF {
return result.toString();
}
- static void convert(String imagePath, String convertedImagePath, int requestedWidth, int requestedHeight, int encodingMethod, boolean convertAsBraille, boolean enableDithering, double ditheringIntensity) throws IOException {
- sample.Image image = loadImage(imagePath, requestedWidth, requestedHeight, convertAsBraille, enableDithering, ditheringIntensity);
+ static void convert(String imagePath, String convertedImagePath, int requestedWidth, int requestedHeight, int encodingMethod, boolean convertAsBraille, boolean enableDithering, double opacity) throws IOException {
+ sample.Image image = loadImage(imagePath, requestedWidth, requestedHeight, convertAsBraille, enableDithering, opacity);
FileOutputStream out = new FileOutputStream(convertedImagePath);