Add files via upload
This commit is contained in:
		
							parent
							
								
									118c27fe35
								
							
						
					
					
						commit
						fa158b126c
					
				
					 5 changed files with 829 additions and 0 deletions
				
			
		
							
								
								
									
										185
									
								
								src/jfxlabproj/GameOfLifeProcessor.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										185
									
								
								src/jfxlabproj/GameOfLifeProcessor.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,185 @@
 | 
				
			||||||
 | 
					// GameOfLifeProcessor.java
 | 
				
			||||||
 | 
					package jfxlabproj.gameoflife;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.concurrent.atomic.AtomicReference;
 | 
				
			||||||
 | 
					import javafx.animation.KeyFrame;
 | 
				
			||||||
 | 
					import javafx.animation.Timeline;
 | 
				
			||||||
 | 
					import javafx.scene.image.Image;
 | 
				
			||||||
 | 
					import javafx.scene.image.ImageView;
 | 
				
			||||||
 | 
					import javafx.scene.image.PixelReader;
 | 
				
			||||||
 | 
					import javafx.scene.image.WritableImage;
 | 
				
			||||||
 | 
					import javafx.scene.paint.Color;
 | 
				
			||||||
 | 
					import javafx.util.Duration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class GameOfLifeProcessor {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static Timeline timeline;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static void startGameOfLife(ImageView imageView) {
 | 
				
			||||||
 | 
					        if (imageView.getImage() == null) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Convert to black and white with chunks
 | 
				
			||||||
 | 
					        Image source = imageView.getImage();
 | 
				
			||||||
 | 
					        int width = 640;
 | 
				
			||||||
 | 
					        int height = (int) (source.getHeight() * (640.0 / source.getWidth()));
 | 
				
			||||||
 | 
					        int chunkSize = 8; // Reduced chunk size for better detail
 | 
				
			||||||
 | 
					        WritableImage bwImage = new WritableImage(width, height);
 | 
				
			||||||
 | 
					        PixelReader reader = source.getPixelReader();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Calculate average brightness and variance of the entire image
 | 
				
			||||||
 | 
					        double totalBrightness = 0;
 | 
				
			||||||
 | 
					        double[] brightnesses = new double[width * height];
 | 
				
			||||||
 | 
					        int pixelCount = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (int y = 0; y < height; y++) {
 | 
				
			||||||
 | 
					            for (int x = 0; x < width; x++) {
 | 
				
			||||||
 | 
					                Color color = reader.getColor(
 | 
				
			||||||
 | 
					                    (int) ((x * source.getWidth()) / 640.0),
 | 
				
			||||||
 | 
					                    (int) ((y * source.getWidth()) / 640.0)
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					                double brightness = color.getBrightness();
 | 
				
			||||||
 | 
					                brightnesses[pixelCount] = brightness;
 | 
				
			||||||
 | 
					                totalBrightness += brightness;
 | 
				
			||||||
 | 
					                pixelCount++;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        double averageBrightness = totalBrightness / pixelCount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Calculate variance
 | 
				
			||||||
 | 
					        double variance = 0;
 | 
				
			||||||
 | 
					        for (int i = 0; i < pixelCount; i++) {
 | 
				
			||||||
 | 
					            variance += Math.pow(brightnesses[i] - averageBrightness, 2);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        variance /= pixelCount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Adjust threshold based on variance
 | 
				
			||||||
 | 
					        double varianceWeight = Math.min(1.0, Math.max(0.1, variance * 10));
 | 
				
			||||||
 | 
					        double threshold = averageBrightness * varianceWeight;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (int y = 0; y < height; y += chunkSize) {
 | 
				
			||||||
 | 
					            for (int x = 0; x < width; x += chunkSize) {
 | 
				
			||||||
 | 
					                double chunkBrightness = 0;
 | 
				
			||||||
 | 
					                int validPixels = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // Calculate average brightness for the chunk
 | 
				
			||||||
 | 
					                for (int cy = 0; cy < chunkSize && (y + cy) < height; cy++) {
 | 
				
			||||||
 | 
					                    for (int cx = 0; cx < chunkSize && (x + cx) < width; cx++) {
 | 
				
			||||||
 | 
					                        Color color = reader.getColor(
 | 
				
			||||||
 | 
					                            (int) (((x + cx) * source.getWidth()) / 640.0),
 | 
				
			||||||
 | 
					                            (int) (((y + cy) * source.getWidth()) / 640.0)
 | 
				
			||||||
 | 
					                        );
 | 
				
			||||||
 | 
					                        chunkBrightness += color.getBrightness();
 | 
				
			||||||
 | 
					                        validPixels++;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                double avgChunkBrightness = chunkBrightness / validPixels;
 | 
				
			||||||
 | 
					                Color chunkColor = (avgChunkBrightness < threshold)
 | 
				
			||||||
 | 
					                    ? Color.BLACK
 | 
				
			||||||
 | 
					                    : Color.WHITE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // Set the color for the entire chunk
 | 
				
			||||||
 | 
					                for (int cy = 0; cy < chunkSize && (y + cy) < height; cy++) {
 | 
				
			||||||
 | 
					                    for (int cx = 0; cx < chunkSize && (x + cx) < width; cx++) {
 | 
				
			||||||
 | 
					                        bwImage
 | 
				
			||||||
 | 
					                            .getPixelWriter()
 | 
				
			||||||
 | 
					                            .setColor(x + cx, y + cy, chunkColor);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        AtomicReference<WritableImage> bwImageRef = new AtomicReference<>(
 | 
				
			||||||
 | 
					            bwImage
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        imageView.setImage(bwImageRef.get());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Start Game of Life
 | 
				
			||||||
 | 
					        timeline = new Timeline(
 | 
				
			||||||
 | 
					            new KeyFrame(Duration.millis(200), event -> {
 | 
				
			||||||
 | 
					                WritableImage nextGeneration = new WritableImage(width, height);
 | 
				
			||||||
 | 
					                PixelReader pixelReader = bwImageRef.get().getPixelReader();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                for (int y = 0; y < height; y += chunkSize) {
 | 
				
			||||||
 | 
					                    for (int x = 0; x < width; x += chunkSize) {
 | 
				
			||||||
 | 
					                        int aliveNeighbors = countAliveNeighbors(
 | 
				
			||||||
 | 
					                            pixelReader,
 | 
				
			||||||
 | 
					                            x,
 | 
				
			||||||
 | 
					                            y,
 | 
				
			||||||
 | 
					                            width,
 | 
				
			||||||
 | 
					                            height,
 | 
				
			||||||
 | 
					                            chunkSize
 | 
				
			||||||
 | 
					                        );
 | 
				
			||||||
 | 
					                        Color currentColor = pixelReader.getColor(x, y);
 | 
				
			||||||
 | 
					                        Color nextColor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        if (currentColor.equals(Color.BLACK)) {
 | 
				
			||||||
 | 
					                            nextColor = (aliveNeighbors == 3 ||
 | 
				
			||||||
 | 
					                                    aliveNeighbors == 2)
 | 
				
			||||||
 | 
					                                ? Color.BLACK
 | 
				
			||||||
 | 
					                                : Color.WHITE;
 | 
				
			||||||
 | 
					                        } else {
 | 
				
			||||||
 | 
					                            nextColor = (aliveNeighbors == 3)
 | 
				
			||||||
 | 
					                                ? Color.BLACK
 | 
				
			||||||
 | 
					                                : Color.WHITE;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        // Set the color for the entire chunk in the next generation
 | 
				
			||||||
 | 
					                        for (
 | 
				
			||||||
 | 
					                            int cy = 0;
 | 
				
			||||||
 | 
					                            cy < chunkSize && (y + cy) < height;
 | 
				
			||||||
 | 
					                            cy++
 | 
				
			||||||
 | 
					                        ) {
 | 
				
			||||||
 | 
					                            for (
 | 
				
			||||||
 | 
					                                int cx = 0;
 | 
				
			||||||
 | 
					                                cx < chunkSize && (x + cx) < width;
 | 
				
			||||||
 | 
					                                cx++
 | 
				
			||||||
 | 
					                            ) {
 | 
				
			||||||
 | 
					                                nextGeneration
 | 
				
			||||||
 | 
					                                    .getPixelWriter()
 | 
				
			||||||
 | 
					                                    .setColor(x + cx, y + cy, nextColor);
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                bwImageRef.set(nextGeneration);
 | 
				
			||||||
 | 
					                imageView.setImage(bwImageRef.get());
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        timeline.setCycleCount(Timeline.INDEFINITE);
 | 
				
			||||||
 | 
					        timeline.play();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static void stopGameOfLife() {
 | 
				
			||||||
 | 
					        if (timeline != null) {
 | 
				
			||||||
 | 
					            timeline.stop();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static int countAliveNeighbors(
 | 
				
			||||||
 | 
					        PixelReader reader,
 | 
				
			||||||
 | 
					        int x,
 | 
				
			||||||
 | 
					        int y,
 | 
				
			||||||
 | 
					        int width,
 | 
				
			||||||
 | 
					        int height,
 | 
				
			||||||
 | 
					        int chunkSize
 | 
				
			||||||
 | 
					    ) {
 | 
				
			||||||
 | 
					        int count = 0;
 | 
				
			||||||
 | 
					        for (int dy = -chunkSize; dy <= chunkSize; dy += chunkSize) {
 | 
				
			||||||
 | 
					            for (int dx = -chunkSize; dx <= chunkSize; dx += chunkSize) {
 | 
				
			||||||
 | 
					                if (dx == 0 && dy == 0) continue;
 | 
				
			||||||
 | 
					                int nx = x + dx;
 | 
				
			||||||
 | 
					                int ny = y + dy;
 | 
				
			||||||
 | 
					                if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
 | 
				
			||||||
 | 
					                    if (reader.getColor(nx, ny).equals(Color.BLACK)) {
 | 
				
			||||||
 | 
					                        count++;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return count;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										113
									
								
								src/jfxlabproj/ImageProcessor.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								src/jfxlabproj/ImageProcessor.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,113 @@
 | 
				
			||||||
 | 
					// ImageProcessor.java
 | 
				
			||||||
 | 
					package jfxlabproj;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import javafx.animation.FadeTransition;
 | 
				
			||||||
 | 
					import javafx.scene.effect.Bloom;
 | 
				
			||||||
 | 
					import javafx.scene.effect.ColorAdjust;
 | 
				
			||||||
 | 
					import javafx.scene.effect.DropShadow;
 | 
				
			||||||
 | 
					import javafx.scene.effect.GaussianBlur;
 | 
				
			||||||
 | 
					import javafx.scene.effect.InnerShadow;
 | 
				
			||||||
 | 
					import javafx.scene.effect.SepiaTone;
 | 
				
			||||||
 | 
					import javafx.scene.image.ImageView;
 | 
				
			||||||
 | 
					import javafx.scene.paint.Color;
 | 
				
			||||||
 | 
					import javafx.util.Duration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class ImageProcessor {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static void applySepia(ImageView imageView) {
 | 
				
			||||||
 | 
					        if (imageView.getImage() != null) {
 | 
				
			||||||
 | 
					            SepiaTone sepia = new SepiaTone(0.7);
 | 
				
			||||||
 | 
					            Bloom bloom = new Bloom(0.2);
 | 
				
			||||||
 | 
					            bloom.setInput(sepia);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            DropShadow shadow = new DropShadow();
 | 
				
			||||||
 | 
					            shadow.setRadius(10.0);
 | 
				
			||||||
 | 
					            shadow.setSpread(0.3);
 | 
				
			||||||
 | 
					            shadow.setColor(Color.rgb(0, 0, 0, 0.4));
 | 
				
			||||||
 | 
					            shadow.setInput(bloom);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            FadeTransition ft = new FadeTransition(
 | 
				
			||||||
 | 
					                Duration.millis(300),
 | 
				
			||||||
 | 
					                imageView
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            ft.setFromValue(0.7);
 | 
				
			||||||
 | 
					            ft.setToValue(1.0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            imageView.setEffect(shadow);
 | 
				
			||||||
 | 
					            ft.play();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static void applyInvert(ImageView imageView) {
 | 
				
			||||||
 | 
					        if (imageView.getImage() != null) {
 | 
				
			||||||
 | 
					            ColorAdjust colorAdjust = new ColorAdjust();
 | 
				
			||||||
 | 
					            colorAdjust.setBrightness(-1.0);
 | 
				
			||||||
 | 
					            colorAdjust.setContrast(0);
 | 
				
			||||||
 | 
					            colorAdjust.setHue(1.0);
 | 
				
			||||||
 | 
					            colorAdjust.setSaturation(-1.0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            InnerShadow innerShadow = new InnerShadow();
 | 
				
			||||||
 | 
					            innerShadow.setRadius(5.0);
 | 
				
			||||||
 | 
					            innerShadow.setColor(Color.rgb(255, 255, 255, 0.3));
 | 
				
			||||||
 | 
					            innerShadow.setInput(colorAdjust);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            FadeTransition ft = new FadeTransition(
 | 
				
			||||||
 | 
					                Duration.millis(300),
 | 
				
			||||||
 | 
					                imageView
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            ft.setFromValue(0.7);
 | 
				
			||||||
 | 
					            ft.setToValue(1.0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            imageView.setEffect(innerShadow);
 | 
				
			||||||
 | 
					            ft.play();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static void applyBlur(ImageView imageView) {
 | 
				
			||||||
 | 
					        if (imageView.getImage() != null) {
 | 
				
			||||||
 | 
					            GaussianBlur blur = new GaussianBlur(15);
 | 
				
			||||||
 | 
					            Bloom bloom = new Bloom(0.3);
 | 
				
			||||||
 | 
					            bloom.setInput(blur);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            DropShadow shadow = new DropShadow();
 | 
				
			||||||
 | 
					            shadow.setRadius(15.0);
 | 
				
			||||||
 | 
					            shadow.setSpread(0.4);
 | 
				
			||||||
 | 
					            shadow.setColor(Color.rgb(0, 0, 0, 0.3));
 | 
				
			||||||
 | 
					            shadow.setInput(bloom);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            FadeTransition ft = new FadeTransition(
 | 
				
			||||||
 | 
					                Duration.millis(300),
 | 
				
			||||||
 | 
					                imageView
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            ft.setFromValue(0.7);
 | 
				
			||||||
 | 
					            ft.setToValue(1.0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            imageView.setEffect(shadow);
 | 
				
			||||||
 | 
					            ft.play();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static void applyGrayscale(ImageView imageView) {
 | 
				
			||||||
 | 
					        if (imageView.getImage() != null) {
 | 
				
			||||||
 | 
					            ColorAdjust grayscale = new ColorAdjust();
 | 
				
			||||||
 | 
					            grayscale.setSaturation(-1);
 | 
				
			||||||
 | 
					            grayscale.setContrast(0.2);
 | 
				
			||||||
 | 
					            grayscale.setBrightness(0.1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            InnerShadow innerShadow = new InnerShadow();
 | 
				
			||||||
 | 
					            innerShadow.setRadius(5.0);
 | 
				
			||||||
 | 
					            innerShadow.setColor(Color.rgb(0, 0, 0, 0.3));
 | 
				
			||||||
 | 
					            innerShadow.setInput(grayscale);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            FadeTransition ft = new FadeTransition(
 | 
				
			||||||
 | 
					                Duration.millis(300),
 | 
				
			||||||
 | 
					                imageView
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            ft.setFromValue(0.7);
 | 
				
			||||||
 | 
					            ft.setToValue(1.0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            imageView.setEffect(innerShadow);
 | 
				
			||||||
 | 
					            ft.play();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										82
									
								
								src/jfxlabproj/MusicPlayer.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								src/jfxlabproj/MusicPlayer.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,82 @@
 | 
				
			||||||
 | 
					package jfxlabproj.musicplayer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.Random;
 | 
				
			||||||
 | 
					import java.util.concurrent.Executors;
 | 
				
			||||||
 | 
					import java.util.concurrent.ScheduledExecutorService;
 | 
				
			||||||
 | 
					import java.util.concurrent.TimeUnit;
 | 
				
			||||||
 | 
					import javafx.scene.image.Image;
 | 
				
			||||||
 | 
					import javafx.scene.image.PixelReader;
 | 
				
			||||||
 | 
					import javafx.scene.paint.Color;
 | 
				
			||||||
 | 
					import javax.sound.sampled.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class MusicPlayer {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static final int BASE_NOTE = 262; // C4 note
 | 
				
			||||||
 | 
					    private ScheduledExecutorService executor;
 | 
				
			||||||
 | 
					    private volatile boolean isPlaying = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void playImageAsMusic(Image image) {
 | 
				
			||||||
 | 
					        if (image == null) return;
 | 
				
			||||||
 | 
					        if (isPlaying) return; // Prevent starting multiple playbacks simultaneously
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        PixelReader reader = image.getPixelReader();
 | 
				
			||||||
 | 
					        int width = (int) image.getWidth();
 | 
				
			||||||
 | 
					        int height = (int) image.getHeight();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        executor = Executors.newScheduledThreadPool(1);
 | 
				
			||||||
 | 
					        isPlaying = true;
 | 
				
			||||||
 | 
					        executor.scheduleAtFixedRate(
 | 
				
			||||||
 | 
					            () -> {
 | 
				
			||||||
 | 
					                Random random = new Random();
 | 
				
			||||||
 | 
					                for (int y = 0; y < height; y++) {
 | 
				
			||||||
 | 
					                    for (int x = 0; x < width; x++) {
 | 
				
			||||||
 | 
					                        if (!isPlaying) return; // Stop processing if paused
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        Color color = reader.getColor(x, y);
 | 
				
			||||||
 | 
					                        double brightness = color.getBrightness();
 | 
				
			||||||
 | 
					                        int note = BASE_NOTE + (int) (brightness * 300); // Vary note based on brightness, reduced range for smoother sound
 | 
				
			||||||
 | 
					                        int duration = 150 + random.nextInt(150); // Randomize duration between 150ms and 300ms
 | 
				
			||||||
 | 
					                        playTone(note, duration, 0.2f); // Reduce volume
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            0,
 | 
				
			||||||
 | 
					            300,
 | 
				
			||||||
 | 
					            TimeUnit.MILLISECONDS
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void pauseMusic() {
 | 
				
			||||||
 | 
					        if (executor != null) {
 | 
				
			||||||
 | 
					            isPlaying = false;
 | 
				
			||||||
 | 
					            executor.shutdown();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private void playTone(int hz, int duration, float volume) {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            byte[] buf = new byte[1];
 | 
				
			||||||
 | 
					            AudioFormat audioFormat = new AudioFormat(44100, 8, 1, true, false);
 | 
				
			||||||
 | 
					            SourceDataLine sdl = AudioSystem.getSourceDataLine(audioFormat);
 | 
				
			||||||
 | 
					            sdl.open(audioFormat);
 | 
				
			||||||
 | 
					            sdl.start();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            FloatControl volumeControl = (FloatControl) sdl.getControl(
 | 
				
			||||||
 | 
					                FloatControl.Type.MASTER_GAIN
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            volumeControl.setValue(20f * (float) Math.log10(volume)); // Set volume level
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            for (int i = 0; i < (duration * 44100) / 1000; i++) {
 | 
				
			||||||
 | 
					                double angle = (i / (44100.0 / hz)) * 2.0 * Math.PI;
 | 
				
			||||||
 | 
					                buf[0] = (byte) (Math.sin(angle) * 100.0); // Reduce amplitude for a softer sound
 | 
				
			||||||
 | 
					                sdl.write(buf, 0, 1);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            sdl.drain();
 | 
				
			||||||
 | 
					            sdl.stop();
 | 
				
			||||||
 | 
					            sdl.close();
 | 
				
			||||||
 | 
					        } catch (LineUnavailableException e) {
 | 
				
			||||||
 | 
					            e.printStackTrace();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										374
									
								
								src/jfxlabproj/TheImaniPulator.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										374
									
								
								src/jfxlabproj/TheImaniPulator.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,374 @@
 | 
				
			||||||
 | 
					package jfxlabproj;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.awt.image.BufferedImage;
 | 
				
			||||||
 | 
					import java.io.File;
 | 
				
			||||||
 | 
					import java.io.IOException;
 | 
				
			||||||
 | 
					import javafx.application.Application;
 | 
				
			||||||
 | 
					import javafx.embed.swing.SwingFXUtils;
 | 
				
			||||||
 | 
					import javafx.geometry.Insets;
 | 
				
			||||||
 | 
					import javafx.geometry.Pos;
 | 
				
			||||||
 | 
					import javafx.scene.Scene;
 | 
				
			||||||
 | 
					import javafx.scene.control.Alert;
 | 
				
			||||||
 | 
					import javafx.scene.control.Alert.AlertType;
 | 
				
			||||||
 | 
					import javafx.scene.control.Button;
 | 
				
			||||||
 | 
					import javafx.scene.control.Label;
 | 
				
			||||||
 | 
					import javafx.scene.image.Image;
 | 
				
			||||||
 | 
					import javafx.scene.image.ImageView;
 | 
				
			||||||
 | 
					import javafx.scene.layout.GridPane;
 | 
				
			||||||
 | 
					import javafx.scene.layout.HBox;
 | 
				
			||||||
 | 
					import javafx.scene.layout.VBox;
 | 
				
			||||||
 | 
					import javafx.scene.paint.Color;
 | 
				
			||||||
 | 
					import javafx.scene.paint.Paint;
 | 
				
			||||||
 | 
					import javafx.stage.FileChooser;
 | 
				
			||||||
 | 
					import javafx.stage.Stage;
 | 
				
			||||||
 | 
					import javax.imageio.ImageIO;
 | 
				
			||||||
 | 
					import jfxlabproj.gameoflife.GameOfLifeProcessor;
 | 
				
			||||||
 | 
					import jfxlabproj.musicplayer.MusicPlayer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class TheImaniPulator extends Application {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private ImageView imageView;
 | 
				
			||||||
 | 
					    private Image originalImage;
 | 
				
			||||||
 | 
					    private MusicPlayer musicPlayer;
 | 
				
			||||||
 | 
					    private Button activeButton = null;
 | 
				
			||||||
 | 
					    private Label statusLabel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public void start(Stage primaryStage) {
 | 
				
			||||||
 | 
					        primaryStage.setTitle("Image Processor");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Scene welcomeScene = WelcomeScreen.createScene(primaryStage);
 | 
				
			||||||
 | 
					        primaryStage.setScene(welcomeScene);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        primaryStage.show();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public Scene createMainScene(Stage primaryStage) {
 | 
				
			||||||
 | 
					        HBox root = new HBox(30);
 | 
				
			||||||
 | 
					        root.setAlignment(Pos.CENTER);
 | 
				
			||||||
 | 
					        root.setStyle("-fx-background-color: #F5F5F7;");
 | 
				
			||||||
 | 
					        root.setPadding(new Insets(30));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        VBox leftSide = new VBox(20);
 | 
				
			||||||
 | 
					        leftSide.setAlignment(Pos.CENTER);
 | 
				
			||||||
 | 
					        leftSide.setStyle(
 | 
				
			||||||
 | 
					            "-fx-background-color: white; -fx-background-radius: 20; -fx-padding: 20;" +
 | 
				
			||||||
 | 
					            "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.1), 10, 0, 0, 5);"
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        imageView = new ImageView();
 | 
				
			||||||
 | 
					        imageView.setFitWidth(400);
 | 
				
			||||||
 | 
					        imageView.setFitHeight(500);
 | 
				
			||||||
 | 
					        imageView.setPreserveRatio(true);
 | 
				
			||||||
 | 
					        imageView.setStyle(
 | 
				
			||||||
 | 
					            "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.1), 10, 0, 0, 5);"
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        statusLabel = new Label("Image Processor");
 | 
				
			||||||
 | 
					        statusLabel.setStyle(
 | 
				
			||||||
 | 
					            "-fx-font-family: 'SF Pro Display'; -fx-font-size: 18px; " +
 | 
				
			||||||
 | 
					            "-fx-font-weight: bold; -fx-text-fill: #1D1D1F;"
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Button loadButton = new Button("Choose Image");
 | 
				
			||||||
 | 
					        styleButton(loadButton);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        leftSide.getChildren().addAll(imageView, loadButton, statusLabel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        VBox rightSide = new VBox(15);
 | 
				
			||||||
 | 
					        rightSide.setAlignment(Pos.TOP_CENTER);
 | 
				
			||||||
 | 
					        rightSide.setPrefWidth(400);
 | 
				
			||||||
 | 
					        rightSide.setStyle(
 | 
				
			||||||
 | 
					            "-fx-background-color: white; -fx-background-radius: 20; -fx-padding: 30;" +
 | 
				
			||||||
 | 
					            "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.1), 10, 0, 0, 5);"
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Label titleLabel = new Label("Image Processor");
 | 
				
			||||||
 | 
					        titleLabel.setStyle(
 | 
				
			||||||
 | 
					            "-fx-font-family: 'SF Pro Display'; -fx-font-size: 32px; -fx-font-weight: bold;"
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        titleLabel.setTextFill(Paint.valueOf("#1D1D1F"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Label filterLabel = new Label("Image Filters");
 | 
				
			||||||
 | 
					        Label saveLabel = new Label("Save Options");
 | 
				
			||||||
 | 
					        Label specialLabel = new Label("Special Effects");
 | 
				
			||||||
 | 
					        Label musicLabel = new Label("Music Controls");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        filterLabel.setStyle("-fx-font-weight: bold; -fx-font-size: 16px;");
 | 
				
			||||||
 | 
					        saveLabel.setStyle("-fx-font-weight: bold; -fx-font-size: 16px;");
 | 
				
			||||||
 | 
					        specialLabel.setStyle("-fx-font-weight: bold; -fx-font-size: 16px;");
 | 
				
			||||||
 | 
					        musicLabel.setStyle("-fx-font-weight: bold; -fx-font-size: 16px;");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Button blurButton = new Button("Blur");
 | 
				
			||||||
 | 
					        Button grayscaleButton = new Button("Grayscale");
 | 
				
			||||||
 | 
					        Button sepiaButton = new Button("Sepia");
 | 
				
			||||||
 | 
					        Button resetButton = new Button("Reset");
 | 
				
			||||||
 | 
					        Button saveAsJpegButton = new Button("Save as JPEG");
 | 
				
			||||||
 | 
					        Button saveAsPngButton = new Button("Save as PNG");
 | 
				
			||||||
 | 
					        Button saveAsHeifButton = new Button("Save as HEIF");
 | 
				
			||||||
 | 
					        Button gameOfLifeButton = new Button("Game of Life");
 | 
				
			||||||
 | 
					        Button playMusicButton = new Button("Play as Music");
 | 
				
			||||||
 | 
					        Button pauseMusicButton = new Button("Pause Music");
 | 
				
			||||||
 | 
					        Button invertButton = new Button("Invert Colors");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        int buttonWidth = 150;
 | 
				
			||||||
 | 
					        for (Button btn : new Button[] {
 | 
				
			||||||
 | 
					            blurButton,
 | 
				
			||||||
 | 
					            grayscaleButton,
 | 
				
			||||||
 | 
					            sepiaButton,
 | 
				
			||||||
 | 
					            resetButton,
 | 
				
			||||||
 | 
					            saveAsJpegButton,
 | 
				
			||||||
 | 
					            saveAsPngButton,
 | 
				
			||||||
 | 
					            saveAsHeifButton,
 | 
				
			||||||
 | 
					            gameOfLifeButton,
 | 
				
			||||||
 | 
					            playMusicButton,
 | 
				
			||||||
 | 
					            pauseMusicButton,
 | 
				
			||||||
 | 
					            invertButton,
 | 
				
			||||||
 | 
					        }) {
 | 
				
			||||||
 | 
					            styleButton(btn);
 | 
				
			||||||
 | 
					            btn.setPrefWidth(buttonWidth);
 | 
				
			||||||
 | 
					            btn.setWrapText(true);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        GridPane filterGrid = new GridPane();
 | 
				
			||||||
 | 
					        filterGrid.setHgap(10);
 | 
				
			||||||
 | 
					        filterGrid.setVgap(10);
 | 
				
			||||||
 | 
					        filterGrid.add(blurButton, 0, 0);
 | 
				
			||||||
 | 
					        filterGrid.add(grayscaleButton, 1, 0);
 | 
				
			||||||
 | 
					        filterGrid.add(sepiaButton, 0, 1);
 | 
				
			||||||
 | 
					        filterGrid.add(resetButton, 1, 1);
 | 
				
			||||||
 | 
					        filterGrid.add(invertButton, 0, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        GridPane saveGrid = new GridPane();
 | 
				
			||||||
 | 
					        saveGrid.setHgap(10);
 | 
				
			||||||
 | 
					        saveGrid.setVgap(10);
 | 
				
			||||||
 | 
					        saveGrid.add(saveAsJpegButton, 0, 0);
 | 
				
			||||||
 | 
					        saveGrid.add(saveAsPngButton, 1, 0);
 | 
				
			||||||
 | 
					        saveGrid.add(saveAsHeifButton, 0, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        GridPane specialGrid = new GridPane();
 | 
				
			||||||
 | 
					        specialGrid.setHgap(10);
 | 
				
			||||||
 | 
					        specialGrid.add(gameOfLifeButton, 0, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        GridPane musicGrid = new GridPane();
 | 
				
			||||||
 | 
					        musicGrid.setHgap(10);
 | 
				
			||||||
 | 
					        musicGrid.add(playMusicButton, 0, 0);
 | 
				
			||||||
 | 
					        musicGrid.add(pauseMusicButton, 1, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        blurButton.setOnAction(e -> {
 | 
				
			||||||
 | 
					            if (originalImage != null) {
 | 
				
			||||||
 | 
					                setActiveButton(blurButton);
 | 
				
			||||||
 | 
					                ImageProcessor.applyBlur(imageView);
 | 
				
			||||||
 | 
					                updateStatus("Blur");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        grayscaleButton.setOnAction(e -> {
 | 
				
			||||||
 | 
					            if (originalImage != null) {
 | 
				
			||||||
 | 
					                setActiveButton(grayscaleButton);
 | 
				
			||||||
 | 
					                ImageProcessor.applyGrayscale(imageView);
 | 
				
			||||||
 | 
					                updateStatus("Grayscale");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        sepiaButton.setOnAction(e -> {
 | 
				
			||||||
 | 
					            if (originalImage != null) {
 | 
				
			||||||
 | 
					                setActiveButton(sepiaButton);
 | 
				
			||||||
 | 
					                ImageProcessor.applySepia(imageView);
 | 
				
			||||||
 | 
					                updateStatus("Sepia");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        invertButton.setOnAction(e -> {
 | 
				
			||||||
 | 
					            if (originalImage != null) {
 | 
				
			||||||
 | 
					                setActiveButton(invertButton);
 | 
				
			||||||
 | 
					                ImageProcessor.applyInvert(imageView);
 | 
				
			||||||
 | 
					                updateStatus("Invert Colors");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        resetButton.setOnAction(e -> {
 | 
				
			||||||
 | 
					            if (originalImage != null) {
 | 
				
			||||||
 | 
					                GameOfLifeProcessor.stopGameOfLife();
 | 
				
			||||||
 | 
					                setActiveButton(null);
 | 
				
			||||||
 | 
					                imageView.setImage(originalImage);
 | 
				
			||||||
 | 
					                imageView.setEffect(null);
 | 
				
			||||||
 | 
					                updateStatus("Image Processor");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        saveAsJpegButton.setOnAction(e -> {
 | 
				
			||||||
 | 
					            saveImage(primaryStage, "jpeg");
 | 
				
			||||||
 | 
					            updateStatus("Saving as JPEG");
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        saveAsPngButton.setOnAction(e -> {
 | 
				
			||||||
 | 
					            saveImage(primaryStage, "png");
 | 
				
			||||||
 | 
					            updateStatus("Saving as PNG");
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        saveAsHeifButton.setOnAction(e -> {
 | 
				
			||||||
 | 
					            saveImage(primaryStage, "heif");
 | 
				
			||||||
 | 
					            updateStatus("Saving as HEIF");
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        gameOfLifeButton.setOnAction(e -> {
 | 
				
			||||||
 | 
					            if (originalImage != null) {
 | 
				
			||||||
 | 
					                setActiveButton(gameOfLifeButton);
 | 
				
			||||||
 | 
					                GameOfLifeProcessor.startGameOfLife(imageView);
 | 
				
			||||||
 | 
					                updateStatus("Game of Life");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        playMusicButton.setOnAction(e -> {
 | 
				
			||||||
 | 
					            if (originalImage != null) {
 | 
				
			||||||
 | 
					                setActiveButton(playMusicButton);
 | 
				
			||||||
 | 
					                musicPlayer = new MusicPlayer();
 | 
				
			||||||
 | 
					                musicPlayer.playImageAsMusic(originalImage);
 | 
				
			||||||
 | 
					                updateStatus("Playing Music");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        pauseMusicButton.setOnAction(e -> {
 | 
				
			||||||
 | 
					            if (musicPlayer != null) {
 | 
				
			||||||
 | 
					                setActiveButton(null);
 | 
				
			||||||
 | 
					                musicPlayer.pauseMusic();
 | 
				
			||||||
 | 
					                updateStatus("Music Paused");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        loadButton.setOnAction(e -> {
 | 
				
			||||||
 | 
					            FileChooser fileChooser = new FileChooser();
 | 
				
			||||||
 | 
					            fileChooser
 | 
				
			||||||
 | 
					                .getExtensionFilters()
 | 
				
			||||||
 | 
					                .add(
 | 
				
			||||||
 | 
					                    new FileChooser.ExtensionFilter(
 | 
				
			||||||
 | 
					                        "Image Files",
 | 
				
			||||||
 | 
					                        "*.png",
 | 
				
			||||||
 | 
					                        "*.jpg",
 | 
				
			||||||
 | 
					                        "*.jpeg",
 | 
				
			||||||
 | 
					                        "*.gif"
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					            File file = fileChooser.showOpenDialog(primaryStage);
 | 
				
			||||||
 | 
					            if (file != null) {
 | 
				
			||||||
 | 
					                Image image = new Image(file.toURI().toString());
 | 
				
			||||||
 | 
					                imageView.setImage(image);
 | 
				
			||||||
 | 
					                originalImage = image;
 | 
				
			||||||
 | 
					                setActiveButton(null);
 | 
				
			||||||
 | 
					                updateStatus("Image Processor");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        rightSide
 | 
				
			||||||
 | 
					            .getChildren()
 | 
				
			||||||
 | 
					            .addAll(
 | 
				
			||||||
 | 
					                titleLabel,
 | 
				
			||||||
 | 
					                filterLabel,
 | 
				
			||||||
 | 
					                filterGrid,
 | 
				
			||||||
 | 
					                saveLabel,
 | 
				
			||||||
 | 
					                saveGrid,
 | 
				
			||||||
 | 
					                specialLabel,
 | 
				
			||||||
 | 
					                specialGrid,
 | 
				
			||||||
 | 
					                musicLabel,
 | 
				
			||||||
 | 
					                musicGrid
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        root.getChildren().addAll(leftSide, rightSide);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Scene scene = new Scene(root, 1000, 700);
 | 
				
			||||||
 | 
					        scene.setFill(Color.web("#F5F5F7"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return scene;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private void updateStatus(String status) {
 | 
				
			||||||
 | 
					        statusLabel.setText(status);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private void setActiveButton(Button button) {
 | 
				
			||||||
 | 
					        if (activeButton != null) {
 | 
				
			||||||
 | 
					            styleButton(activeButton);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        activeButton = button;
 | 
				
			||||||
 | 
					        if (activeButton != null) {
 | 
				
			||||||
 | 
					            activeButton.setStyle(
 | 
				
			||||||
 | 
					                "-fx-background-color: #FFC799;" +
 | 
				
			||||||
 | 
					                "-fx-text-fill: black;" +
 | 
				
			||||||
 | 
					                "-fx-font-family: 'SF Pro Text';" +
 | 
				
			||||||
 | 
					                "-fx-font-size: 16px;" +
 | 
				
			||||||
 | 
					                "-fx-padding: 12px 20px;" +
 | 
				
			||||||
 | 
					                "-fx-background-radius: 10px;" +
 | 
				
			||||||
 | 
					                "-fx-cursor: hand;" +
 | 
				
			||||||
 | 
					                "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.2), 10, 0, 0, 5);"
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private void saveImage(Stage stage, String format) {
 | 
				
			||||||
 | 
					        if (imageView.getImage() != null) {
 | 
				
			||||||
 | 
					            FileChooser fileChooser = new FileChooser();
 | 
				
			||||||
 | 
					            fileChooser.setTitle("Save Image");
 | 
				
			||||||
 | 
					            fileChooser.setInitialFileName("processed_image." + format);
 | 
				
			||||||
 | 
					            fileChooser
 | 
				
			||||||
 | 
					                .getExtensionFilters()
 | 
				
			||||||
 | 
					                .add(
 | 
				
			||||||
 | 
					                    new FileChooser.ExtensionFilter(
 | 
				
			||||||
 | 
					                        format.toUpperCase() + " files",
 | 
				
			||||||
 | 
					                        "*." + format
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					            File file = fileChooser.showSaveDialog(stage);
 | 
				
			||||||
 | 
					            if (file != null) {
 | 
				
			||||||
 | 
					                try {
 | 
				
			||||||
 | 
					                    BufferedImage bufferedImage = SwingFXUtils.fromFXImage(
 | 
				
			||||||
 | 
					                        imageView.getImage(),
 | 
				
			||||||
 | 
					                        null
 | 
				
			||||||
 | 
					                    );
 | 
				
			||||||
 | 
					                    ImageIO.write(bufferedImage, format, file);
 | 
				
			||||||
 | 
					                } catch (IOException ex) {
 | 
				
			||||||
 | 
					                    Alert alert = new Alert(AlertType.ERROR);
 | 
				
			||||||
 | 
					                    alert.setTitle("Error");
 | 
				
			||||||
 | 
					                    alert.setHeaderText("Could not save image");
 | 
				
			||||||
 | 
					                    alert.setContentText("Error: " + ex.getMessage());
 | 
				
			||||||
 | 
					                    alert.showAndWait();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private void styleButton(Button button) {
 | 
				
			||||||
 | 
					        String defaultStyle =
 | 
				
			||||||
 | 
					            "-fx-background-color: #F5F5F7;" +
 | 
				
			||||||
 | 
					            "-fx-text-fill: #1D1D1F;" +
 | 
				
			||||||
 | 
					            "-fx-font-family: 'SF Pro Text';" +
 | 
				
			||||||
 | 
					            "-fx-font-size: 16px;" +
 | 
				
			||||||
 | 
					            "-fx-padding: 12px 20px;" +
 | 
				
			||||||
 | 
					            "-fx-background-radius: 10px;" +
 | 
				
			||||||
 | 
					            "-fx-cursor: hand;" +
 | 
				
			||||||
 | 
					            "-fx-border-color: #D2D2D7;" +
 | 
				
			||||||
 | 
					            "-fx-border-radius: 10px;" +
 | 
				
			||||||
 | 
					            "-fx-border-width: 1px;";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        String hoverStyle =
 | 
				
			||||||
 | 
					            "-fx-background-color: #E8E8ED;" +
 | 
				
			||||||
 | 
					            "-fx-text-fill: #1D1D1F;" +
 | 
				
			||||||
 | 
					            "-fx-font-family: 'SF Pro Text';" +
 | 
				
			||||||
 | 
					            "-fx-font-size: 16px;" +
 | 
				
			||||||
 | 
					            "-fx-padding: 12px 20px;" +
 | 
				
			||||||
 | 
					            "-fx-background-radius: 10px;" +
 | 
				
			||||||
 | 
					            "-fx-cursor: hand;" +
 | 
				
			||||||
 | 
					            "-fx-border-color: #007AFF;" +
 | 
				
			||||||
 | 
					            "-fx-border-radius: 10px;" +
 | 
				
			||||||
 | 
					            "-fx-border-width: 2px;" +
 | 
				
			||||||
 | 
					            "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.1), 5, 0, 0, 2);";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        button.setStyle(defaultStyle);
 | 
				
			||||||
 | 
					        button.setOnMouseEntered(e -> button.setStyle(hoverStyle));
 | 
				
			||||||
 | 
					        button.setOnMouseExited(e -> button.setStyle(defaultStyle));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static void main(String[] args) {
 | 
				
			||||||
 | 
					        launch(args);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										75
									
								
								src/jfxlabproj/WelcomeScreen.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								src/jfxlabproj/WelcomeScreen.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,75 @@
 | 
				
			||||||
 | 
					package jfxlabproj;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import javafx.animation.FadeTransition;
 | 
				
			||||||
 | 
					import javafx.geometry.Pos;
 | 
				
			||||||
 | 
					import javafx.scene.Scene;
 | 
				
			||||||
 | 
					import javafx.scene.control.Button;
 | 
				
			||||||
 | 
					import javafx.scene.control.Label;
 | 
				
			||||||
 | 
					import javafx.scene.layout.VBox;
 | 
				
			||||||
 | 
					import javafx.scene.paint.Color;
 | 
				
			||||||
 | 
					import javafx.stage.Stage;
 | 
				
			||||||
 | 
					import javafx.util.Duration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class WelcomeScreen {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static Scene createScene(Stage primaryStage) {
 | 
				
			||||||
 | 
					        VBox root = new VBox(30);
 | 
				
			||||||
 | 
					        root.setAlignment(Pos.CENTER);
 | 
				
			||||||
 | 
					        root.setStyle("-fx-background-color: #1E1E1E;" + "-fx-padding: 40px;");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Label welcomeLabel = new Label("Image Processor");
 | 
				
			||||||
 | 
					        welcomeLabel.setStyle(
 | 
				
			||||||
 | 
					            "-fx-font-family: 'SF Pro Display';" +
 | 
				
			||||||
 | 
					            "-fx-font-size: 48px;" +
 | 
				
			||||||
 | 
					            "-fx-font-weight: bold;" +
 | 
				
			||||||
 | 
					            "-fx-text-fill: #FFFFFF;"
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Label subtitleLabel = new Label("Made by Aadit, Akhil and Saurabh.");
 | 
				
			||||||
 | 
					        subtitleLabel.setStyle(
 | 
				
			||||||
 | 
					            "-fx-font-family: 'SF Pro Text';" +
 | 
				
			||||||
 | 
					            "-fx-font-size: 18px;" +
 | 
				
			||||||
 | 
					            "-fx-text-fill: #BBBBBB;"
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Button nextButton = new Button("Get Started");
 | 
				
			||||||
 | 
					        nextButton.setStyle(
 | 
				
			||||||
 | 
					            "-fx-background-color: #0F0F0F;" +
 | 
				
			||||||
 | 
					            "-fx-text-fill: white;" +
 | 
				
			||||||
 | 
					            "-fx-font-family: 'SF Pro Text';" +
 | 
				
			||||||
 | 
					            "-fx-font-size: 16px;" +
 | 
				
			||||||
 | 
					            "-fx-padding: 12px 24px;" +
 | 
				
			||||||
 | 
					            "-fx-background-radius: 8px;" +
 | 
				
			||||||
 | 
					            "-fx-cursor: hand;"
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        nextButton.setOnMouseEntered(e ->
 | 
				
			||||||
 | 
					            nextButton.setStyle(
 | 
				
			||||||
 | 
					                nextButton.getStyle() + "-fx-background-color: #0071E3;"
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        nextButton.setOnMouseExited(e ->
 | 
				
			||||||
 | 
					            nextButton.setStyle(
 | 
				
			||||||
 | 
					                nextButton.getStyle() + "-fx-background-color: #0F0F0F;"
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        nextButton.setOnAction(e -> {
 | 
				
			||||||
 | 
					            FadeTransition ft = new FadeTransition(Duration.millis(300), root);
 | 
				
			||||||
 | 
					            ft.setFromValue(1.0);
 | 
				
			||||||
 | 
					            ft.setToValue(0.0);
 | 
				
			||||||
 | 
					            ft.setOnFinished(event -> {
 | 
				
			||||||
 | 
					                TheImaniPulator mainApp = new TheImaniPulator();
 | 
				
			||||||
 | 
					                primaryStage.setScene(mainApp.createMainScene(primaryStage));
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            ft.play();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        root.getChildren().addAll(welcomeLabel, subtitleLabel, nextButton);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Scene scene = new Scene(root, 800, 600);
 | 
				
			||||||
 | 
					        scene.setFill(Color.web("#1E1E1E"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return scene;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue