Question

In this assignment you will be developing an image manipulation program. The remaining laboratory assignments will build on tHandler Methods Your user interface does not need to match Figure 1 but does need to facilitate all of the functionality in a. Load and reload images stored in the following image file formats: jpg, png, tiff, and .msoe. o Note that large . msoe imThe save button will open a FileChooser dialog box that will allow the user to select the destination folder and type in the

Java

Thank you!!

0 0
Add a comment Improve this question Transcribed image text
Answer #1

ImageIO.java

import javafx.embed.swing.SwingFXUtils;
import javafx.scene.image.Image;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.ByteBuffer;
import java.util.Scanner;

public class ImageIO {

    /**
     *
     * @param file File location to be read
     * @return BufferedImage containing the Image data
     */
    public BufferedImage read(File file) throws IOException, CorruptDataException, NumberFormatException {
        String[] fileNameParts = file.getName().split("\\.");
        BufferedImage image = null;

        switch (fileNameParts[fileNameParts.length - 1]) {
            case "msoe":
                image = readMSOE(file);
                break;
            case "bmsoe":
                image = readBMSOE(file);
                break;
            default:
                image = SwingFXUtils.fromFXImage(new Image(file.toURI().toURL().toString()), null);
                break;
        }
        return image;
    }

    /**
     * General write method. Decides what kind of file is being written and calls appropriate helper methods
     * @param image Image to be written
     * @param file File Location to be written to
     */
    public void write(BufferedImage image, File file) throws IOException {
        //Split into filename, extension
        String[] fileNameParts = file.getName().split("\\.");
        //Extension letters
        String extension = fileNameParts[fileNameParts.length-1];

        switch (extension) {
            case "msoe":
                writeMSOE(image, file);
                break;
            case "bmsoe":
                writeBMSOE(image, file);
                break;
            default:
                //Write the buffered image with the extension where file points it to.
                javax.imageio.ImageIO.write(image, extension, file);
                break;
        }
    }

    /**
     * Turns a .msoe file into a Image class
     * @param file File pointing to file
     * @return Image class of .msoe file
     */
    private BufferedImage readMSOE(File file) throws IOException, CorruptDataException, NumberFormatException {
        Scanner scanner = new Scanner(file);
        if(!scanner.nextLine().equals("MSOE")){
            throw new CorruptDataException("MSOE File Is Corrupt: Doesn't contain MSOE on first line.");
        }
        String[] numberArgs = scanner.nextLine().split(" ");
        int width = Integer.parseInt(numberArgs[0]);
        int height = Integer.parseInt(numberArgs[1]);
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width && scanner.hasNext(); x++) {
                String color = scanner.next();
                int red = Integer.valueOf(color.substring(1, 3), 16);
                int green = Integer.valueOf(color.substring(3, 5), 16);
                int blue = Integer.valueOf(color.substring(5, 7), 16);
                int alpha = Integer.valueOf(color.substring(7), 16);
                image.setRGB(x, y, new Color(red, green, blue, alpha).getRGB());
            }
        }

        scanner.close();
        return image;
    }

    /**
     * Turns a .bmsoe file into a Image class
     * @param file File pointing to file
     * @return Image class of .bmsoe file
     */
    private BufferedImage readBMSOE(File file) throws IOException, CorruptDataException {
        //Set up the stream which references the file
        FileInputStream fileInputStream = new FileInputStream(file);
        //DataInStream is easier to use than FileInStream, needs an existing stream to initialize
        DataInputStream inputStream = new DataInputStream(fileInputStream);

        //One char one byte, 5 bytes gets us 5 chars. They should be B-M-S-O-E
        byte[] data = new byte[5];
        inputStream.read(data);

        //Used to combine the characters
        String fileHeader = "";

        //Interpret the bytes to chars, then combine them into a string
        int i = 0;
        while (i < (data.length)){
            fileHeader += Character.toString((char)data[i]);
            i++;
        }

        //Check the letters
        if(!fileHeader.equals("BMSOE")){
            throw new CorruptDataException("BMSOE file header not found");
        }

        //Set input byte size to 4. Thats the size of an Integer
        data = new byte[4];

        //Get the width
        inputStream.read(data);
        int width = ByteBuffer.wrap(data).getInt();

        //Get the height
        inputStream.read(data);
        int height = ByteBuffer.wrap(data).getInt();

        //Image to be filled, and returned
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

        //X and Y coords of the pixels
        int x = 0;
        int y = 0;
        while(x<width-1||y<height-1){
            //Get next 4 bytes of data, one byte per color
            inputStream.read(data);

            //Create the color by passing each byte-long integer into the args for R,G,B,A
            Color color = new Color(data[0]&0xff, data[1]&0xff, data[2]&0xff, data[3]&0xff);

            //Set the color at the pixel spot
            image.setRGB(x, y, color.getRGB());

            //If reached the end of the row of the pixels
            if(++x >= width){
                //Remember the 16 byte rule. Skip any "leftover" bytes
                inputStream.skipBytes((x*4)%16);
                x = 0;
                y++;
            }
        }
        //CLOSE THE STREAMS
        fileInputStream.close();
        inputStream.close();
        return image;
    }

    /**
     * Writes the image to where file points it
     * @param image Generic image class
     * @param file .msoe file
     */
    private void writeMSOE(BufferedImage image, File file) throws IOException {
        FileWriter writer = new FileWriter(file);
        writer.append("MSOE"+System.lineSeparator());
        writer.append(image.getWidth() + " " + image.getHeight() + System.lineSeparator());
        for(int y = 0; y < image.getHeight(); y++){
            for(int x = 0; x < image.getWidth(); x++){
                Color color = new Color(image.getRGB(x, y));
                String red = String.format("%02X", color.getRed());
                String green = String.format("%02X", color.getGreen());
                String blue = String.format("%02X", color.getBlue());
                String alpha = String.format("%02X", color.getAlpha());
                writer.write("#"+red+green+blue+alpha+" ");
            }
            writer.append(System.lineSeparator());
            writer.flush();
        }
        writer.close();
    }

    /**
     * Writes the image to where file points it
     * @param image Generic image class
     * @param file .bmsoe file
     */
    private void writeBMSOE(BufferedImage image, File file) throws IOException {
        //Basic input stream of the specified file
        FileOutputStream outputStream = new FileOutputStream(file);
        //Data input stream is easier to use than file input stream, needs an existing input stream to work
        DataOutputStream dataOutputStream = new DataOutputStream(outputStream);

        //Wrtites the string BMSOE to binary, convert to char array first because they are similar
        char[] letters = "BMSOE".toCharArray();
        for (char c: letters){
            dataOutputStream.write((byte)c);
        }

        //Integers are 4 bytes, don't need to do anything fancy for writing the dimensions
        dataOutputStream.writeInt(image.getWidth());
        dataOutputStream.writeInt(image.getHeight());

        //Initialize loop variables. data is reused, x and y are reference points for the pixels, avoids nested loop
        byte[] data = new byte[4];
        int x = 0;
        int y = 0;

        //While there are still pixels to loop through, use this instead of nested for loop
        while(x<image.getWidth()-1||y<image.getHeight()-1){
            //Get current pixel
            Color c = new Color(image.getRGB(x,y));

            //Write red, green, blue, alpha
            data[0] = (byte)c.getRed();
            data[1] = (byte)c.getGreen();
            data[2] = (byte)c.getBlue();
            data[3] = (byte)c.getAlpha();

            //Write current pixel
            for(byte b: data){
                dataOutputStream.write(b);
            }

            //If we reached the end of the row
            if(++x>image.getWidth()-1){
                //For the remaining bytes to be written to keep the 16 byte rule, write a byte
                for(int i = 0; i < (x*4)%16; i++){
                    dataOutputStream.writeByte(0);
                }
                x=0;
                y++;
            }
        }
        dataOutputStream.close();
        outputStream.close();
    }
}

Controller.java

import javafx.embed.swing.SwingFXUtils;
import javafx.event.EventHandler;
import javafx.fxml.FXML;

import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TextInputDialog;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.input.MouseEvent;
import javafx.stage.FileChooser;
import javafx.stage.Stage;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.*;
import java.lang.reflect.Array;

public class Controller {

    public void initialize() throws IOException {
        filterWindow = new Stage();
        FXMLLoader fxmlLoader = new FXMLLoader();
        final Parent fxmlRoot =
                fxmlLoader.load(
                        new FileInputStream(new File("kernel.fxml")));
        filterWindow.setScene(new Scene(fxmlRoot));
        filterWindow.setTitle("Filter Window");
        KernelController kernelController = fxmlLoader.getController();
        kernelController.setController(this);

        imageViewer.addEventHandler(MouseEvent.MOUSE_CLICKED, mouseClick);
    }

    /**Current file being displayed and worked on.*/
    private File selectedImageFile;
    /**Current loaded image*/
    private BufferedImage selectedImage;

    /**Used to keep track of selected meme status.*/
    private boolean stickerSelected = false;

    Transformation red = (x, y, color)->{
        return new Color(color.getRed(), 0, 0, color.getAlpha());
    };

    Transformation grayscale = (x,y,color)->{
        int red = (int)(color.getRed()*.2126);
        int green = (int)(color.getGreen()*.7152);
        int blue = (int)(color.getBlue()*.0722);
        //int alpha = (int)(color.getAlpha())
        int finalColor = red+green+blue;
        System.out.println(color.getAlpha());
        return new Color(finalColor, finalColor, finalColor, color.getAlpha());
    };

    /**Used in file chooser to filter out unwanted image formats.*/
    private static final FileChooser.ExtensionFilter[] FILE_FILTERS = new FileChooser.ExtensionFilter[]{
            new FileChooser.ExtensionFilter("All Images","*.gif", "*.jpg", "*.bmsoe", "*.msoe", "*.png"),
            new FileChooser.ExtensionFilter("GIF","*.gif"),
            new FileChooser.ExtensionFilter("JPEG","*.jpg"),
            new FileChooser.ExtensionFilter("BMSOE","*.bmsoe"),
            new FileChooser.ExtensionFilter("MSOE","*.msoe"),
            new FileChooser.ExtensionFilter("PNG","*.png")
    };

    @FXML
    //GUI component used to display image
    private ImageView imageViewer;

    @FXML
    /**
     * Writes the current selected image, otherwise it opens save as dialog.
     */
    private void save(){
        if(selectedImageFile ==null||selectedImage==null){
            saveAs();
        }else{
            ImageIO imageIO = new ImageIO();
            try {
                imageIO.write(selectedImage, selectedImageFile);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * Takes currently selected image and writes it to file.
     * @param outputFile File locatio to write to.
     */
    private void save(File outputFile){
        ImageIO imageWrite = new ImageIO();
        try {
            imageWrite.write(selectedImage, outputFile);
        } catch (IOException e) {
            displayError("Error Encountered While Trying To Save: "+ selectedImageFile.getAbsolutePath(), e.getMessage());
        }
    }

    @FXML
    /**
     * Opens file save dialog and used ImageIO to save to that file
     */
    private void saveAs(){
        FileChooser chooser = new FileChooser();
        chooser.getExtensionFilters().addAll(FILE_FILTERS);
        File writeFile = chooser.showSaveDialog(null);

        if(writeFile==null)
            return;

        save(writeFile);
    }

    @FXML
    /**
     * Opens open file dialog. If user cancels nothing happens
     */
    private void open(){
        //File chooser dialog
        FileChooser chooser = new FileChooser();
        chooser.getExtensionFilters().addAll(FILE_FILTERS);
        File imageFile = chooser.showOpenDialog(null);
        if(imageFile!=null){
            selectedImageFile = imageFile;
            reload();
        }
    }

    @FXML
    /**
     * Goes back to location of currently selected image file and loads it again.
     * If the image has been edited between refreshes, it will reflect said chanes.
     */
    private void reload() {
        //User may cancel, or select an illegal file type
        if(selectedImageFile!=null && selectedImageFile.exists()){
            try{
                ImageIO imageIO = new ImageIO();
                setImage(imageIO.read(selectedImageFile));
            }catch (IOException e){
                displayError("Error Encountered While Trying To Load: "+ selectedImageFile.getAbsolutePath(), e.getMessage());
            } catch (CorruptDataException e) {
                displayError("Error Encountered While Trying To Load: "+ selectedImageFile.getAbsolutePath() +"\n File is corrupt", e.getMessage());
            }catch (NumberFormatException e){
                displayError("Error Encountered While Trying To Load: "+ selectedImageFile.getAbsolutePath() +"\n File is corrupt", e.getMessage());
            }catch (ArrayIndexOutOfBoundsException e){
                displayError("Error Encountered While Trying To Load: " + selectedImageFile.getAbsolutePath() + "\n File is corrupt", e.getMessage());
            }
        }
    }

    private void displayError(String contentText, String message) {
        Alert alert = new Alert(Alert.AlertType.ERROR);
        alert.setContentText(contentText);
        alert.showAndWait();
        ErrorLogger.Log(message);
    }

    /**
     * Applies transformation to the BufferedImage
     * @param transformation Color scheme transformation
     * @param bufferedImage Image that you want to change
     * @return A transformed image
     */
    private BufferedImage transform(Transformation transformation, BufferedImage bufferedImage){
        for(int i = 0; i < bufferedImage.getWidth(); i++){
            for (int k = 0; k < bufferedImage.getHeight(); k++){
                bufferedImage.setRGB(i, k , transformation.transform(i, k, new Color(bufferedImage.getRGB(i,k))).getRGB());
            }
        }
        return bufferedImage;
    }

    @FXML
    /**
     * Turns the selected image to grayscale, mutates original BufferedImage
     */
    private void makeGrayscale(){
        setImage(transform(grayscale, selectedImage));
    }

    @FXML
    /**
     * Turns selected image negative, does mutate BufferedImage
     */
    private void makeNegative(){
        Transformation negative = (x,y,color)->{
            return new Color(255-color.getRed(), 255-color.getGreen(), 255-color.getBlue());
        };
        setImage(transform(negative,selectedImage));
    }

    @FXML
    /**
     * Removes the green and blue channels of the image
     */
    private void makeRed(){
        setImage(transform(red, selectedImage));
    }

    @FXML
    private void makeRedGray(){
        Transformation transformation;
        for(int y = 0; y < selectedImage.getHeight(); y++){
            if(y%2 == 0){
                transformation = red;
            }else{
                transformation = grayscale;
            }
            for(int x = 0; x < selectedImage.getWidth(); x++){
                selectedImage.setRGB(x, y, transformation.transform(x, y, new Color(selectedImage.getRGB(x,y))).getRGB());
            }
        }
        setImage(selectedImage);
    }

    Stage filterWindow;

    @FXML
    private void showFilter() throws IOException {
        filterWindow.show();
    }

    BufferedImage image;

    @FXML
    EventHandler mouseClick = event -> {
        if(event.getEventType() == MouseEvent.MOUSE_CLICKED && stickerSelected){
            double pixelDensityX = selectedImage.getWidth()/imageViewer.getFitWidth();
            double pixelDensityY = selectedImage.getHeight()/imageViewer.getFitHeight();

            int x = (int)(((MouseEvent)event).getX()*pixelDensityX);
            int y = (int)(((MouseEvent)event).getY()*pixelDensityY);

            int i = 0;
            int k = 0;

            while(i < image.getWidth() || k < image.getHeight()){
                if(i < image.getWidth() && x+i < selectedImage.getWidth() && k < image.getHeight() && y+k < selectedImage.getHeight()){
                    selectedImage.setRGB(x+i, y+k, image.getRGB(i, k));
                }
                if(++i > selectedImage.getWidth()){
                    i = 0;
                    k++;
                }
            }
            setImage(selectedImage);
        }
    };

    @FXML
    CheckBox checkBox;

    @FXML
    private void selectSticker(){
        stickerSelected = checkBox.isSelected();

        if(stickerSelected) {
            //File chooser dialog
            FileChooser chooser = new FileChooser();
            chooser.getExtensionFilters().addAll(FILE_FILTERS);
            File imageFile = chooser.showOpenDialog(null);

            ImageIO imageIO = new ImageIO();
            try {
                image = imageIO.read(imageFile);
            } catch (IOException e) {
                displayError("Error Encountered While Trying To Load: " + selectedImageFile.getAbsolutePath() + "\n File is corrupt", e.getMessage());
                ErrorLogger.Log(e.getMessage());
            } catch (CorruptDataException e) {
                displayError("Error Encountered While Trying To Load: " + selectedImageFile.getAbsolutePath() + "\n File is corrupt", e.getMessage());
                ErrorLogger.Log(e.getMessage());
            }
        }
    }

    /**
     * Helper method which allows for easy setting of the image. Removes confusing BufferedImage and fx image
     * ambiguity
     * @param image BufferedImage to be shown
     */
    public void setImage(BufferedImage image){
        selectedImage = image;
        imageViewer.setImage(SwingFXUtils.toFXImage(selectedImage, null));
    }

    public BufferedImage getImage() {
        return selectedImage;
    }

    @FXML
    /**
     * Clears the error log log.txt
     */
    private void clearLog(){
        ErrorLogger.clearLog();
    }
}

Add a comment
Know the answer?
Add Answer to:
Java Thank you!! In this assignment you will be developing an image manipulation program. The remaining...
Your Answer:

Post as a guest

Your Name:

What's your source?

Earn Coins

Coins can be redeemed for fabulous gifts.

Not the answer you're looking for? Ask your own homework help question. Our experts will answer your question WITHIN MINUTES for Free.
Similar Homework Help Questions
  • Java program that creates a photo album application.    Which will load a collection of images...

    Java program that creates a photo album application.    Which will load a collection of images and displays them in a album layout. The program will allow the user to tag images with metadata: •Title for the photo .      Limited to 100 characters. •Description for the photo . Limited to 300 characters. •Date taken •Place taken Functional Specs 1.Your album should be able to display the pictures sorted by Title, Date, and Place. 2.When the user clicks on a photo,...

  • This is Visual Basic program, thank you for your help In this assignment, you'll start a...

    This is Visual Basic program, thank you for your help In this assignment, you'll start a new Windows Forms application. Assume we have the data shown below: Names_first={"jack","marjy","tom","luke","sam","al","joe","miky","lu"} Name_last={"jones","ety","fan","spence","amin",sid","bud","ant","ben"} Amounts={234.45,8293.1,943.25,27381.0,271.39,7436.12,2743.0,1639.95,2354.2} The above will allows us to emulate reading data from a file, which we will learn in the next unit. For now, we will assume the data above has been read from a file. We need to process this data in fast way. For that purpose, we need to: Declare...

  • Assignment Λ You shall write a Java program that accepts 5 command-line arguments and generates an image of a Sierpinski triangle, as a 24- bit RGB PNG image file. Specifications The command-line arg...

    Assignment Λ You shall write a Java program that accepts 5 command-line arguments and generates an image of a Sierpinski triangle, as a 24- bit RGB PNG image file. Specifications The command-line arguments shall consist of the following 1. The width (in pixels) of the image, as a positive decimal integer 2. The height (in pixels) of the image, as a positive decimal integer 3. The minimum area (in pixels) that a triangle must have in order to be drawn,...

  • Java FX Application Purpose The purpose of this assignment is to get you familiar with the...

    Java FX Application Purpose The purpose of this assignment is to get you familiar with the basics of the JavaFX GUI interface components. This assignment will cover Labels, Fonts, Basic Images, and Layouts. You will use a StackPane and a BorderPane to construct the layout to the right. In addition you will use the Random class to randomly load an image when the application loads Introduction The application sets the root layout to a BorderPane. The BorderPane can be divided...

  • Assignment You will be developing a speeding ticket fee calculator. This program will ask for a t...

    Assignment You will be developing a speeding ticket fee calculator. This program will ask for a ticket file, which is produced by a central police database, and your program will output to a file or to the console depending on the command line arguments. Furthermore, your program will restrict the output to the starting and ending dates given by the user. The ticket fee is calculated using four multipliers, depending on the type of road the ticket was issued: Interstate...

  • JAVA PROGRAM USING ECLIPSE. THE FIRST IMAGE IS THE INSTRUCTIONS, THE SECOND IS THE OUTPUT TEST...

    JAVA PROGRAM USING ECLIPSE. THE FIRST IMAGE IS THE INSTRUCTIONS, THE SECOND IS THE OUTPUT TEST CASES(WHAT IM TRYING TO PRODUCE) BELOW THOSE IMAGES ARE THE .JAVA FILES THAT I HAVE CREATED. THESE ARE GeometircObject.Java,Point.java, and Tester.Java. I just need help making the Rectangle.java and Rectangle2D.java classes. GeometricObject.Java: public abstract class GeometricObject { private String color = "white"; // shape color private boolean filled; // fill status protected GeometricObject() { // POST: default shape is unfilled blue this.color = "blue";...

  • could you please help me with this problem, also I need a little text so I...

    could you please help me with this problem, also I need a little text so I can understand how you solved the problem? import java.io.File; import java.util.Scanner; /** * This program lists the files in a directory specified by * the user. The user is asked to type in a directory name. * If the name entered by the user is not a directory, a * message is printed and the program ends. */ public class DirectoryList { public static...

  • Help with java . For this project, you will design and implement a program that analyzes...

    Help with java . For this project, you will design and implement a program that analyzes baby name popularities in data provided by the Social Security Administration. Every 10 years, the data gives the 1,000 most popular boy and girl names for kids born in the United States. The data can be boiled down to a single text file as shown below. On each line we have the name, followed by the rank of that name in 1900, 1910, 1920,...

  • Mountain Paths (Part 1) Objectives 2d arrays Store Use Nested Loops Parallel data structures (i.e...

    Mountain Paths (Part 1) in C++ Objectives 2d arrays Store Use Nested Loops Parallel data structures (i.e. parallel arrays … called multiple arrays in the zyBook) Transform data Read from files Write to files structs Code Requirements Start with this code: mtnpathstart.zip Do not modify the function signatures provided. Do not #include or #include Program Flow Read the data into a 2D array Find min and max elevation to correspond to darkest and brightest color, respectively Compute the shade of...

  • JAVA Hello I am trying to add a menu to my Java code if someone can...

    JAVA Hello I am trying to add a menu to my Java code if someone can help me I would really appreacite it thank you. I found a java menu code but I dont know how to incorporate it to my code this is the java menu code that i found. import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.ButtonGroup; import javax.swing.JCheckBoxMenuItem; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JRadioButtonMenuItem; public class MenuExp extends JFrame { public MenuExp() { setTitle("Menu Example");...

ADVERTISEMENT
Free Homework Help App
Download From Google Play
Scan Your Homework
to Get Instant Free Answers
Need Online Homework Help?
Ask a Question
Get Answers For Free
Most questions answered within 3 hours.
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT