com.imesha.imageprocessor.controllers.MainController.java Source code

Java tutorial

Introduction

Here is the source code for com.imesha.imageprocessor.controllers.MainController.java

Source

/*
 * The MIT License (MIT)
 * Copyright (c) 2016 2016
 * <p>
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 * <p>
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 * <p>
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

package com.imesha.imageprocessor.controllers;

import com.imesha.imageprocessor.util.ImageAnalyser;
import com.imesha.imageprocessor.util.ImageConverter;
import com.imesha.imageprocessor.util.ImageSampler;
import com.imesha.imageprocessor.util.ImageUtils;
import com.imesha.imageprocessor.util.compression.CompressedImage;
import com.imesha.imageprocessor.util.compression.CompressorFactory;
import com.imesha.imageprocessor.util.compression.ImageCompressor;
import javafx.application.Platform;
import javafx.embed.swing.SwingFXUtils;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.stage.FileChooser;
import org.apache.commons.io.FileUtils;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Formatter;
import java.util.Locale;
import java.util.ResourceBundle;

public class MainController implements Initializable {
    @FXML
    private MenuItem openMenuItem;
    @FXML
    private Pane parentPane;

    @FXML
    private ImageView imageView;
    @FXML
    private ImageView previousImageView;
    @FXML
    private ImageView additionalImageView;

    @FXML
    private Button processButton;

    @FXML
    private Label messageLabel;

    private BufferedImage bufferedImage;
    private BufferedImage originalGrayImage;

    public void initialize(URL location, ResourceBundle resources) {
        setOpenMenuItemActionListener();
        setProcessButtonActionListener();
    }

    private void setProcessButtonActionListener() {
        this.processButton.setOnAction(new EventHandler<ActionEvent>() {
            public void handle(ActionEvent event) {
                new Thread() {
                    public void run() {
                        try {
                            // 1. Convert the image to gray scale and show in UI
                            BufferedImage grayImage = ImageConverter.convertToGrayScale(bufferedImage);
                            bufferedImage = grayImage;
                            originalGrayImage = ImageUtils.deepCopy(grayImage);
                            MainController.showImageInUI(grayImage, imageView);
                            MainController.showMessage("Converted to Gray Scale", messageLabel);
                            System.out.println(bufferedImage.getWidth() + "x" + bufferedImage.getHeight());

                            // 2. The image will be down sampled and showed in the UI.
                            BufferedImage downSampledImage = ImageSampler.downSample(bufferedImage);
                            bufferedImage = downSampledImage;
                            MainController.showImageInUI(downSampledImage, previousImageView);
                            MainController.showMessage("Down sampled", messageLabel);
                            System.out.println(bufferedImage.getWidth() + "x" + bufferedImage.getHeight());

                            // 3. The down sampled image will then be up sampled
                            BufferedImage upSampledImage = ImageSampler.upSample(bufferedImage);
                            bufferedImage = upSampledImage;
                            MainController.showImageInUI(upSampledImage, additionalImageView);
                            MainController.showMessage("Up sampled", messageLabel);
                            System.out.println(bufferedImage.getWidth() + "x" + bufferedImage.getHeight());

                            // 4. Calculate and show the statistics.
                            calculateAndShowDistortion();

                            //Compress Images
                            ImageCompressor compressor = CompressorFactory.getInstance()
                                    .getCompressor(CompressorFactory.RUN_LENGTH_CODING);
                            CompressedImage compressedImage = compressor.compress(originalGrayImage);

                            // Write the compressed image to a file.
                            FileUtils.writeStringToFile(new File("/tmp/compress.rlc"),
                                    compressedImage.getBinaryRepresentation());

                            // Decompress the image
                            BufferedImage decompressedImage = compressor.decompress(compressedImage);
                            MainController.showImageInUI(decompressedImage, additionalImageView);

                        } catch (Exception e) {
                            System.out.println(e.getMessage());
                            e.printStackTrace();
                        }
                    }
                }.start();
            }
        });
    }

    private void setOpenMenuItemActionListener() {
        // Open an image, then show the image in the imageView
        openMenuItem.setOnAction(new EventHandler<ActionEvent>() {
            public void handle(ActionEvent event) {
                FileChooser.ExtensionFilter extensionFilter = new FileChooser.ExtensionFilter("Images", "*.*");
                FileChooser fileChooser = new FileChooser();
                fileChooser.getExtensionFilters().add(extensionFilter);
                fileChooser.setTitle("Select an Image to be opened");
                File file = fileChooser.showOpenDialog(parentPane.getScene().getWindow());
                if (file == null)
                    return;
                try {
                    bufferedImage = ImageIO.read(file);
                    MainController.showImageInUI(bufferedImage, imageView);
                } catch (IOException e) {
                    System.out.println(e.getMessage());
                }
            }
        });
    }

    /**
     * Calculates the distortion between the original gray image and the final up sampled image
     */
    private void calculateAndShowDistortion() {
        try {
            double distortion = ImageAnalyser.calculateAverageDistortion(this.originalGrayImage,
                    this.bufferedImage);
            double sd = ImageAnalyser.calculateStandardDeviation(this.originalGrayImage, this.bufferedImage);
            StringBuilder stringBuilder = new StringBuilder();
            Formatter formatter = new Formatter(stringBuilder, Locale.US);
            formatter.format("Distortion : \n\t%.2f\nSD : \n\t%.2f", distortion, sd);
            MainController.showMessage(formatter.toString(), messageLabel);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Show a given BufferedImage in the UI.
     *
     * @param bufferedImage The image to be shown in the UI
     * @param imageView     The JavaFX ImageView element in which the BufferedImage to be shown.
     */
    private static void showImageInUI(final BufferedImage bufferedImage, final ImageView imageView) {
        Platform.runLater(new Runnable() {
            public void run() {
                Image loadedImage = SwingFXUtils.toFXImage(bufferedImage, null);
                imageView.setImage(loadedImage);
                imageView.setPreserveRatio(true);
                imageView.setSmooth(true);
                imageView.setCache(true);
            }
        });
    }

    /**
     * Utility method to show a given message in the message are of the UI.
     *
     * @param message      The message to be displayed
     * @param messageLabel The @{@link Label} object in which the message should be displayed
     */
    private static void showMessage(final String message, final Label messageLabel) {
        Platform.runLater(new Runnable() {
            public void run() {
                messageLabel.setText(message);
            }
        });
    }

}