From f671d526f083aebd14e8093a662a034f3f144c51 Mon Sep 17 00:00:00 2001 From: Remizov Kirirll Date: Sun, 16 Mar 2025 18:43:04 +0300 Subject: [PATCH] Added all pointed filters --- .../org/example/lab_1/Helpers/Helpers.java | 19 + .../example/lab_1/ImageEditorController.java | 347 +++++++++++++++++- .../org/example/lab_1/main-view.fxml | 19 +- 3 files changed, 381 insertions(+), 4 deletions(-) diff --git a/lab_1/src/main/java/org/example/lab_1/Helpers/Helpers.java b/lab_1/src/main/java/org/example/lab_1/Helpers/Helpers.java index e9ee2e7..7e25138 100644 --- a/lab_1/src/main/java/org/example/lab_1/Helpers/Helpers.java +++ b/lab_1/src/main/java/org/example/lab_1/Helpers/Helpers.java @@ -9,4 +9,23 @@ public class Helpers { } return val; } + public static double NormolizeIdealOtr(double val) { + if (val > 1) { + return 1; + } else if (val < 0) { + return 0; + } + return val; + } + public static void sortArray(int[] array) { + for (int i = 0; i < array.length - 1; i++) { + for (int j = i + 1; j < array.length; j++) { + if (array[i] > array[j]) { + int temp = array[i]; + array[i] = array[j]; + array[j] = temp; + } + } + } + } } diff --git a/lab_1/src/main/java/org/example/lab_1/ImageEditorController.java b/lab_1/src/main/java/org/example/lab_1/ImageEditorController.java index 351b570..e8713f2 100644 --- a/lab_1/src/main/java/org/example/lab_1/ImageEditorController.java +++ b/lab_1/src/main/java/org/example/lab_1/ImageEditorController.java @@ -10,22 +10,33 @@ import javafx.scene.control.ProgressBar; import javafx.stage.FileChooser; import javafx.stage.Stage; import static org.example.lab_1.Helpers.Helpers.CheckBit; +import static org.example.lab_1.Helpers.Helpers.NormolizeIdealOtr; +import static org.example.lab_1.Helpers.Helpers.sortArray; public class ImageEditorController { @FXML private ImageView imageView; + private Image oldImg; @FXML private ProgressBar progressBar; public void initialize() { progressBar.setVisible(false); - String imageUrl = "https://s0.rbk.ru/v6_top_pics/media/img/7/15/756775857541157.jpg"; + String imageUrl = "https://i.pinimg.com/originals/a9/1c/2e/a91c2ed53bdd4c8d236b82828ea99505.jpg"; Image defaultImage = new Image(imageUrl); imageView.setImage(defaultImage); } + public void returnToOldImage() { + if(imageView.getImage() == oldImg || oldImg == null){ + return; + } else { + imageView.setImage(oldImg); + } + } + public void openFile() { FileChooser fileChooser = new FileChooser(); fileChooser.setTitle("Выберите изображение"); @@ -41,6 +52,7 @@ public class ImageEditorController { public void applyInversionFilter() { progressBar.setVisible(true); + oldImg = imageView.getImage(); Image image = imageView.getImage(); if (image == null) return; @@ -77,6 +89,7 @@ public class ImageEditorController { public void GrayScaleFilter() { progressBar.setVisible(true); + oldImg = imageView.getImage(); Image img = imageView.getImage(); if(img == null){ return; } @@ -115,6 +128,7 @@ public class ImageEditorController { public void Sepia() { progressBar.setVisible(true); + oldImg = imageView.getImage(); Image img = imageView.getImage(); if(img == null){ return; } @@ -137,7 +151,7 @@ public class ImageEditorController { double grey = 0.299 * r + 0.587 * g + 0.144 * b; - int k = 32; + int k = 20; double f; r = CheckBit((int) grey+(2*k), 0, 255); f = grey+(0.5*k); @@ -148,9 +162,336 @@ public class ImageEditorController { Writer.setArgb(x, y, newArgb); } } - imageView.setImage(SepiaImg); System.out.println("Применён Sepia"); progressBar.setVisible(false); } + + public void GetYarc() { + progressBar.setVisible(true); + oldImg = imageView.getImage(); + Image img = imageView.getImage(); + if (img == null) { + return; + } + + int w = (int) img.getWidth(); + int h = (int) img.getHeight(); + + WritableImage YarcImg = new WritableImage(w, h); + + PixelReader Reader = img.getPixelReader(); + PixelWriter Writer = YarcImg.getPixelWriter(); + + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) { + int argb = Reader.getArgb(x, y); + + int a = (argb >> 24) & 0xFF; + int r = (argb >> 16) & 0xFF; + int g = (argb >> 8) & 0xFF; + int b = argb & 0xFF; + + double grey = 0.299 * r + 0.587 * g + 0.144 * b; + + int k = 20; + r = Math.min(255, r + k); + g = Math.min(255, g + k); + b = Math.min(255, b + k); + + int newArgb = (a << 24) | (r << 16) | (g << 8) | b; + Writer.setArgb(x, y, newArgb); + } + } + imageView.setImage(YarcImg); + System.out.println("Применёно Увеличение яркости"); + progressBar.setVisible(false); + } + + public void Sdvig() { + progressBar.setVisible(true); + oldImg = imageView.getImage(); + Image img = imageView.getImage(); + if(img == null){ return; } + + int w = (int) img.getWidth(); + int h = (int) img.getHeight(); + + WritableImage SdvigImg = new WritableImage(w, h); + + PixelReader Reader = img.getPixelReader(); + PixelWriter Writer = SdvigImg.getPixelWriter(); + + for(int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) { + if(x < 50){ + continue; + } + int argb = Reader.getArgb(x - 50, y); + + int a = (argb >> 24) & 0xFF; + int r = (argb >> 16) & 0xFF; + int g = (argb >> 8) & 0xFF; + int b = argb & 0xFF; + + int newArgb = (a << 24) | (r << 16) | (g << 8) | b; + Writer.setArgb(x, y, newArgb); + } + } + imageView.setImage(SdvigImg); + System.out.println("Применён Сдвиг"); + progressBar.setVisible(false); + } + + public void grayWorld() { + progressBar.setVisible(true); + oldImg = imageView.getImage(); + Image img = imageView.getImage(); + if(img == null){ return; } + + int w = (int) img.getWidth(); + int h = (int) img.getHeight(); + + PixelReader pixelReader = img.getPixelReader(); + + double sumR = 0, sumG = 0, sumB = 0; + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) { + int argb = pixelReader.getArgb(x, y); + + int r = (argb >> 16) & 0xFF; + int g = (argb >> 8) & 0xFF; + int b = argb & 0xFF; + + sumR += r; + sumG += g; + sumB += b; + } + } + + double avgR = sumR / (w * h); + double avgG = sumG / (w * h); + double avgB = sumB / (w * h); + + double avgGray = (avgR + avgG + avgB) / 3; + + double scaleR = avgGray / avgR; + double scaleG = avgGray / avgG; + double scaleB = avgGray / avgB; + + WritableImage GWImage = new WritableImage(w, h); + PixelWriter pixelWriter = GWImage.getPixelWriter(); + + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) { + int argb = pixelReader.getArgb(x, y); + + int a = (argb >> 24) & 0xFF; + int r = (argb >> 16) & 0xFF; + int g = (argb >> 8) & 0xFF; + int b = argb & 0xFF; + + int newR = (int) Math.min(255, r * scaleR); + int newG = (int) Math.min(255, g * scaleG); + int newB = (int) Math.min(255, b * scaleB); + + int newArgb = (a << 24) | (newR << 16) | (newG << 8) | newB; + pixelWriter.setArgb(x, y, newArgb); + } + } + + imageView.setImage(GWImage); + System.out.println("Применен фильтр 'Серый мир'"); + progressBar.setVisible(false); + } + + public void autoLevels() { + progressBar.setVisible(true); + oldImg = imageView.getImage(); + Image img = imageView.getImage(); + if(img == null) { return; } + + int w = (int) img.getWidth(); + int h = (int) img.getHeight(); + + PixelReader reader = img.getPixelReader(); + + int rMin = 127, rMax = 127, gMin = 127, gMax = 127, bMin = 127, bMax = 127; + for(int y = 0; y < h; y++) { + for (int x = 0; x < w; x++){ + int argb = reader.getArgb(x, y); + + int a = (argb >> 24) & 0xFF; + int r = (argb >> 16) & 0xFF; + int g = (argb >> 8) & 0xFF; + int b = argb & 0xFF; + + if(r < rMin) { + rMin = r; + } else if (r > rMax) { + rMax = r; + } + + if(g < gMin) { + gMin = g; + } else if (g > gMax) { + gMax = g; + } + + if(b < bMin) { + bMin = b; + } else if (b > bMax) { + bMax = b; + } + } + } + + WritableImage autolevelImg = new WritableImage(w, h); + PixelWriter writer = autolevelImg.getPixelWriter(); + + for(int y = 0; y < h; y++) { + for (int x = 0; x < w; x++){ + int argb = reader.getArgb(x, y); + + int a = (argb >> 24) & 0xFF; + int r = (argb >> 16) & 0xFF; + int g = (argb >> 8) & 0xFF; + int b = argb & 0xFF; + + double _r = ((r - rMin) / (rMax - rMin)) * 255; + r = CheckBit((int) _r , 0 , 255); + + double _g = ((g - gMin) / (gMax - gMin)) * 255; + g = CheckBit((int) _g , 0 , 255); + + double _b = ((b - bMin) / (bMax - bMin)) * 255; + b = CheckBit((int) _b , 0 , 255); + + int newArgb = (a << 24) | (r << 16) | (g << 8) | b; + writer.setArgb(x, y, newArgb); + } + } + + imageView.setImage(autolevelImg); + System.out.println("Применен фильтр 'Автолевел'"); + progressBar.setVisible(false); + } + + public void IDdealOtr() { + progressBar.setVisible(true); + oldImg = imageView.getImage(); + Image img = imageView.getImage(); + if(img == null) { return; } + + int w = (int) img.getWidth(); + int h = (int) img.getHeight(); + + PixelReader reader = img.getPixelReader(); + + int rMax = 127, gMax = 127, bMax = 127; + for(int y = 0; y < h; y++) { + for (int x = 0; x < w; x++){ + int argb = reader.getArgb(x, y); + + int a = (argb >> 24) & 0xFF; + int r = (argb >> 16) & 0xFF; + int g = (argb >> 8) & 0xFF; + int b = argb & 0xFF; + + if(r > rMax) { + rMax = r; + } + + if(g > gMax) { + gMax = g; + } + + if(b > bMax) { + bMax = b; + } + } + } + + WritableImage IdealOtrImg = new WritableImage(w, h); + PixelWriter writer = IdealOtrImg.getPixelWriter(); + + for(int y = 0; y < h; y++) { + for (int x = 0; x < w; x++){ + int argb = reader.getArgb(x, y); + + int a = (argb >> 24) & 0xFF; + int r = (argb >> 16) & 0xFF; + int g = (argb >> 8) & 0xFF; + int b = argb & 0xFF; + + double _r = NormolizeIdealOtr(r/rMax); + double _g = NormolizeIdealOtr(g/gMax); + double _b = NormolizeIdealOtr(b/bMax); + + r = (int) _r * 255; + g = (int) _g * 255; + b = (int) _b * 255; + + int newArgb = (a << 24) | (r << 16) | (g << 8) | b; + writer.setArgb(x, y, newArgb); + } + } + imageView.setImage(IdealOtrImg); + System.out.println("Применен фильтр 'Идеальный отражатель'"); + progressBar.setVisible(false); + } + + public void applyMedianFilter() { + progressBar.setVisible(true); + oldImg = imageView.getImage(); + Image img = imageView.getImage(); + if (img == null) { + return; + } + + int w = (int) img.getWidth(); + int h = (int) img.getHeight(); + + PixelReader reader = img.getPixelReader(); + WritableImage medianImg = new WritableImage(w, h); + PixelWriter writer = medianImg.getPixelWriter(); + + for (int y = 1; y < h - 1; y++) { + for (int x = 1; x < w - 1; x++) { + int[] redValues = new int[9]; + int[] greenValues = new int[9]; + int[] blueValues = new int[9]; + int index = 0; + + for (int dy = -1; dy <= 1; dy++) { + for (int dx = -1; dx <= 1; dx++) { + int argb = reader.getArgb(x + dx, y + dy); + redValues[index] = (argb >> 16) & 0xFF; // Красный канал + greenValues[index] = (argb >> 8) & 0xFF; // Зеленый канал + blueValues[index] = argb & 0xFF; // Синий канал + index++; + } + } + + sortArray(redValues); + sortArray(greenValues); + sortArray(blueValues); + + + int medianRed = redValues[4]; + int medianGreen = greenValues[4]; + int medianBlue = blueValues[4]; + + int a = (reader.getArgb(x, y) >> 24) & 0xFF; + + int newArgb = (a << 24) | (medianRed << 16) | (medianGreen << 8) | medianBlue; + writer.setArgb(x, y, newArgb); + } + } + + imageView.setImage(medianImg); + System.out.println("Применен фильтр 'Медиана'"); + progressBar.setVisible(false); + } + } diff --git a/lab_1/src/main/resources/org/example/lab_1/main-view.fxml b/lab_1/src/main/resources/org/example/lab_1/main-view.fxml index 3ec224f..a605b95 100644 --- a/lab_1/src/main/resources/org/example/lab_1/main-view.fxml +++ b/lab_1/src/main/resources/org/example/lab_1/main-view.fxml @@ -8,6 +8,7 @@ + @@ -19,9 +20,20 @@ + + + + + + - + + + + + + @@ -32,4 +44,9 @@ + + + + +