Added all pointed filters

This commit is contained in:
Remizov Kirirll 2025-03-16 18:43:04 +03:00
parent aa90d4e4b2
commit f671d526f0
3 changed files with 381 additions and 4 deletions

View File

@ -9,4 +9,23 @@ public class Helpers {
} }
return val; 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;
}
}
}
}
} }

View File

@ -10,22 +10,33 @@ import javafx.scene.control.ProgressBar;
import javafx.stage.FileChooser; import javafx.stage.FileChooser;
import javafx.stage.Stage; import javafx.stage.Stage;
import static org.example.lab_1.Helpers.Helpers.CheckBit; 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 { public class ImageEditorController {
@FXML @FXML
private ImageView imageView; private ImageView imageView;
private Image oldImg;
@FXML @FXML
private ProgressBar progressBar; private ProgressBar progressBar;
public void initialize() { public void initialize() {
progressBar.setVisible(false); 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); Image defaultImage = new Image(imageUrl);
imageView.setImage(defaultImage); imageView.setImage(defaultImage);
} }
public void returnToOldImage() {
if(imageView.getImage() == oldImg || oldImg == null){
return;
} else {
imageView.setImage(oldImg);
}
}
public void openFile() { public void openFile() {
FileChooser fileChooser = new FileChooser(); FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Выберите изображение"); fileChooser.setTitle("Выберите изображение");
@ -41,6 +52,7 @@ public class ImageEditorController {
public void applyInversionFilter() { public void applyInversionFilter() {
progressBar.setVisible(true); progressBar.setVisible(true);
oldImg = imageView.getImage();
Image image = imageView.getImage(); Image image = imageView.getImage();
if (image == null) return; if (image == null) return;
@ -77,6 +89,7 @@ public class ImageEditorController {
public void GrayScaleFilter() { public void GrayScaleFilter() {
progressBar.setVisible(true); progressBar.setVisible(true);
oldImg = imageView.getImage();
Image img = imageView.getImage(); Image img = imageView.getImage();
if(img == null){ return; } if(img == null){ return; }
@ -115,6 +128,7 @@ public class ImageEditorController {
public void Sepia() { public void Sepia() {
progressBar.setVisible(true); progressBar.setVisible(true);
oldImg = imageView.getImage();
Image img = imageView.getImage(); Image img = imageView.getImage();
if(img == null){ return; } if(img == null){ return; }
@ -137,7 +151,7 @@ public class ImageEditorController {
double grey = 0.299 * r + 0.587 * g + 0.144 * b; double grey = 0.299 * r + 0.587 * g + 0.144 * b;
int k = 32; int k = 20;
double f; double f;
r = CheckBit((int) grey+(2*k), 0, 255); r = CheckBit((int) grey+(2*k), 0, 255);
f = grey+(0.5*k); f = grey+(0.5*k);
@ -148,9 +162,336 @@ public class ImageEditorController {
Writer.setArgb(x, y, newArgb); Writer.setArgb(x, y, newArgb);
} }
} }
imageView.setImage(SepiaImg); imageView.setImage(SepiaImg);
System.out.println("Применён Sepia"); System.out.println("Применён Sepia");
progressBar.setVisible(false); 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);
}
} }

View File

@ -8,6 +8,7 @@
<?import javafx.scene.layout.BorderPane?> <?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.VBox?> <?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Button?>
<BorderPane xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.lab_1.ImageEditorController"> <BorderPane xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.lab_1.ImageEditorController">
<top> <top>
<MenuBar> <MenuBar>
@ -19,9 +20,20 @@
<MenuItem text="Инверсия" onAction="#applyInversionFilter"/> <MenuItem text="Инверсия" onAction="#applyInversionFilter"/>
<MenuItem text="Оттенки серого" onAction="#GrayScaleFilter"/> <MenuItem text="Оттенки серого" onAction="#GrayScaleFilter"/>
<MenuItem text="Сепия" onAction="#Sepia"/> <MenuItem text="Сепия" onAction="#Sepia"/>
<MenuItem text="Увеличить яркость" onAction="#GetYarc"/>
<MenuItem text="Сдвиг" onAction="#Sdvig"/>
<MenuItem text="Серый мир" onAction="#grayWorld"/>
<MenuItem text="Автоуровни" onAction="#autoLevels"/>
<MenuItem text="Идеальный отражатель" onAction="#IDdealOtr" />
<MenuItem text="Медиана" onAction="#applyMedianFilter"/>
</Menu> </Menu>
<Menu text="Матричные"> <Menu text="Матричные">
<!-- Пустое подменю --> <MenuItem text="Тиснение" />
<MenuItem text="Разматие в движении" />
<MenuItem text="Разширение" />
<MenuItem text="Сужение" />
<MenuItem text="Фильтр Собеля" />
<MenuItem text="Фильтр Щарра" />
</Menu> </Menu>
</Menu> </Menu>
</MenuBar> </MenuBar>
@ -32,4 +44,9 @@
<ProgressBar fx:id="progressBar" prefWidth="400"/> <ProgressBar fx:id="progressBar" prefWidth="400"/>
</VBox> </VBox>
</center> </center>
<bottom>
<VBox alignment="CENTER" spacing="50" >
<Button onAction="#returnToOldImage">Вернуть к начальному состоянию</Button>
</VBox>
</bottom>
</BorderPane> </BorderPane>