Added all pointed filters
This commit is contained in:
parent
aa90d4e4b2
commit
f671d526f0
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user