Skip to main content

Image Viewer GUI 3.0

Implementasi Object-Oriented Programming dari Image Viewer, merupakan modifikasi dari postingan Image Viewer GUI yang sebelumnya, library yang dibutuhkan :
  1. Awt (Event, Image, Color, Event)
  2. Swing
  3. File IO
Class yang diimplementasikan antara lain :
  1. ImageViewer (Sebagai main class yang melakukan display image pada aplikasi GUI)
  2. ImagePanel (Sebagai class yang menampilkan OFImage serta menambah functionality)
  3. ImageFileManager (Sebagai class utility untuk melakukan load image)
  4. OFImage (Sebagai class yang mendefinisikan image sebagai object)
  5. Abstract Class Filter (Sebagai class yang mengatur fungsional filter yang berguna untuk memanipulasi gambar) dioverride oleh :
    1. DarkerFilter (Sebagai class yang berfungsi untuk mengubah gambar menjadi lebih gelap)
    2. LighterFilter (Sebagai class yang berfungsi untuk mengubah gambar menjadi lebih terang)
    3. ThresholdFilter (Sebagai class yang berfungsi untuk mengubah gambar dari warna menjadi gambar grayscale)
    4. FishEyeFilter (Sebagai class yang berfungsi untuk mengubah gambar menjadi efek yang mirip seperti lensa fisheye -> efek lengkung)

Source Code

ImageViewer
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import javax.swing.border.*;

import java.io.File;

import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;

/**
 * Sebagai main class yang melakukan display image pada aplikasi GUI
 *
 * Untuk memulai aplikasi, diperlukan instansi objek dari class ini
 *
 * @author Satria Ade Veda Karuniawan
 * @version 3.0
 */
public class ImageViewer
{
    private static final String VERSION = "Version 3.0";
    private static JFileChooser fileChooser = new JFileChooser(System.getProperty("user.dir"));

    private JFrame frame;
    private ImagePanel imagePanel;
    private JLabel filenameLabel;
    private JLabel statusLabel;
    private JButton smallerButton;
    private JButton largerButton;
    private OFImage currentImage;
 
    private List<Filter> filters;
 
    /**
     * Create an ImageViewer and display its GUI on screen.
     */
    public ImageViewer()
    {
        currentImage = null;
        filters = createFilters();
        makeFrame();
    }


    // ---- implementation of menu functions ----
 
    /**
     * Open function: open a file chooser to select a new image file,
     * and then display the chosen image.
     */
    private void openFile()
    {
        int returnVal = fileChooser.showOpenDialog(frame);

        if(returnVal != JFileChooser.APPROVE_OPTION) {
            return;  // cancelled
        }
        File selectedFile = fileChooser.getSelectedFile();
        currentImage = ImageFileManager.loadImage(selectedFile);
     
        if(currentImage == null) {   // image file was not a valid image
            JOptionPane.showMessageDialog(frame,
                    "The file was not in a recognized image file format.",
                    "Image Load Error",
                    JOptionPane.ERROR_MESSAGE);
            return;
        }

        imagePanel.setImage(currentImage);
        setButtonsEnabled(true);
        showFilename(selectedFile.getPath());
        showStatus("File loaded.");
        frame.pack();
    }

    /**
     * Close function: close the current image.
     */
    private void close()
    {
        currentImage = null;
        imagePanel.clearImage();
        showFilename(null);
        setButtonsEnabled(false);
    }

    /**
     * Save As function: save the current image to a file.
     */
    private void saveAs()
    {
        if(currentImage != null) {
            int returnVal = fileChooser.showSaveDialog(frame);
 
            if(returnVal != JFileChooser.APPROVE_OPTION) {
                return;  // cancelled
            }
            File selectedFile = fileChooser.getSelectedFile();
            ImageFileManager.saveImage(currentImage, selectedFile);
         
            showFilename(selectedFile.getPath());
        }
    }

    /**
     * Quit function: quit the application.
     */
    private void quit()
    {
        System.exit(0);
    }

    /**
     * Apply a given filter to the current image.
     *
     * @param filter   The filter object to be applied.
     */
    private void applyFilter(Filter filter)
    {
        if(currentImage != null) {
            filter.apply(currentImage);
            frame.repaint();
            showStatus("Applied: " + filter.getName());
        }
        else {
            showStatus("No image loaded.");
        }
    }

    /**
     * 'About' function: show the 'about' box.
     */
    private void showAbout()
    {
        JOptionPane.showMessageDialog(frame,
                    "ImageViewer\n" + VERSION,
                    "About ImageViewer",
                    JOptionPane.INFORMATION_MESSAGE);
    }

    /**
     * Make the current picture larger.
     */
    private void makeLarger()
    {
        if(currentImage != null) {
            // create new image with double size
            int width = currentImage.getWidth();
            int height = currentImage.getHeight();
            OFImage newImage = new OFImage(width * 2, height * 2);

            // copy pixel data into new image
            for(int y = 0; y < height; y++) {
                for(int x = 0; x < width; x++) {
                    Color col = currentImage.getPixel(x, y);
                    newImage.setPixel(x * 2, y * 2, col);
                    newImage.setPixel(x * 2 + 1, y * 2, col);
                    newImage.setPixel(x * 2, y * 2 + 1, col);
                    newImage.setPixel(x * 2+1, y * 2 + 1, col);
                }
            }
         
            currentImage = newImage;
            imagePanel.setImage(currentImage);
            frame.pack();
        }
    }

    /**
     * Make the current picture smaller.
     */
    private void makeSmaller()
    {
        if(currentImage != null) {
            // create new image with double size
            int width = currentImage.getWidth() / 2;
            int height = currentImage.getHeight() / 2;
            OFImage newImage = new OFImage(width, height);

            // copy pixel data into new image
            for(int y = 0; y < height; y++) {
                for(int x = 0; x < width; x++) {
                    newImage.setPixel(x, y, currentImage.getPixel(x * 2, y * 2));
                }
            }
         
            currentImage = newImage;
            imagePanel.setImage(currentImage);
            frame.pack();
        }
    }
 
    // ---- support methods ----

    /**
     * Show the file name of the current image in the fils display label.
     * 'null' may be used as a parameter if no file is currently loaded.
     *
     * @param filename  The file name to be displayed, or null for 'no file'.
     */
    private void showFilename(String filename)
    {
        if(filename == null) {
            filenameLabel.setText("No file displayed.");
        }
        else {
            filenameLabel.setText("File: " + filename);
        }
    }

    /**
     * Show a message in the status bar at the bottom of the screen.
     * @param text The message to be displayed.
     */
    private void showStatus(String text)
    {
        statusLabel.setText(text);
    }

    /**
     * Enable or disable all toolbar buttons.
     *
     * @param status  'true' to enable the buttons, 'false' to disable.
     */
    private void setButtonsEnabled(boolean status)
    {
        smallerButton.setEnabled(status);
        largerButton.setEnabled(status);
    }

    /**
     * Create a list with all the known filters.
     * @return The list of filters.
     */
    private List<Filter> createFilters()
    {
        List<Filter> filterList = new ArrayList<Filter>();
        filterList.add(new DarkerFilter("Darker"));
        filterList.add(new LighterFilter("Lighter"));
        filterList.add(new ThresholdFilter("Threshold"));
        filterList.add(new FishEyeFilter("Fish Eye"));
     
        return filterList;
    }
 
    // ---- swing stuff to build the frame and all its components ----
 
    /**
     * Create the Swing frame and its content.
     */
    private void makeFrame()
    {
        frame = new JFrame("ImageViewer");
        JPanel contentPane = (JPanel)frame.getContentPane();
        contentPane.setBorder(new EmptyBorder(6, 6, 6, 6));

        makeMenuBar(frame);
     
        // Specify the layout manager with nice spacing
        contentPane.setLayout(new BorderLayout(6, 6));

        // Create the image pane in the center
        imagePanel = new ImagePanel();
        imagePanel.setBorder(new EtchedBorder());
        contentPane.add(imagePanel, BorderLayout.CENTER);
     
        // Create two labels at top and bottom for the file name and status message
        filenameLabel = new JLabel();
        contentPane.add(filenameLabel, BorderLayout.NORTH);

        statusLabel = new JLabel(VERSION);
        contentPane.add(statusLabel, BorderLayout.SOUTH);
     
        // Create the toolbar with the buttons
        JPanel toolbar = new JPanel();
        toolbar.setLayout(new GridLayout(0, 1));
     
        smallerButton = new JButton("Smaller");
        smallerButton.addActionListener(new ActionListener() {
                               public void actionPerformed(ActionEvent e) { makeSmaller(); }
                           });
        toolbar.add(smallerButton);
     
        largerButton = new JButton("Larger");
        largerButton.addActionListener(new ActionListener() {
                               public void actionPerformed(ActionEvent e) { makeLarger(); }
                           });
        toolbar.add(largerButton);

        // Add toolbar into panel with flow layout for spacing
        JPanel flow = new JPanel();
        flow.add(toolbar);
     
        contentPane.add(flow, BorderLayout.WEST);
     
        // building is done - arrange the components   
        showFilename(null);
        setButtonsEnabled(false);
        frame.pack();
     
        // place the frame at the center of the screen and show
        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
        frame.setLocation(d.width/2 - frame.getWidth()/2, d.height/2 - frame.getHeight()/2);
        frame.setVisible(true);
    }
 
    /**
     * Create the main frame's menu bar.
     *
     * @param frame   The frame that the menu bar should be added to.
     */
    private void makeMenuBar(JFrame frame)
    {
        final int SHORTCUT_MASK =
            Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();

        JMenuBar menubar = new JMenuBar();
        frame.setJMenuBar(menubar);
     
        JMenu menu;
        JMenuItem item;
     
        // create the File menu
        menu = new JMenu("File");
        menubar.add(menu);
     
        item = new JMenuItem("Open...");
            item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, SHORTCUT_MASK));
            item.addActionListener(new ActionListener() {
                               public void actionPerformed(ActionEvent e) { openFile(); }
                           });
        menu.add(item);

        item = new JMenuItem("Close");
            item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W, SHORTCUT_MASK));
            item.addActionListener(new ActionListener() {
                               public void actionPerformed(ActionEvent e) { close(); }
                           });
        menu.add(item);
        menu.addSeparator();

        item = new JMenuItem("Save As...");
            item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, SHORTCUT_MASK));
            item.addActionListener(new ActionListener() {
                               public void actionPerformed(ActionEvent e) { saveAs(); }
                           });
        menu.add(item);
        menu.addSeparator();
     
        item = new JMenuItem("Quit");
            item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, SHORTCUT_MASK));
            item.addActionListener(new ActionListener() {
                               public void actionPerformed(ActionEvent e) { quit(); }
                           });
        menu.add(item);

        // create the Filter menu
        menu = new JMenu("Filter");
        menubar.add(menu);
     
        for(final Filter filter : filters) {
            item = new JMenuItem(filter.getName());
            item.addActionListener(new ActionListener() {
                                public void actionPerformed(ActionEvent e) {
                                    applyFilter(filter);
                                }
                           });
             menu.add(item);
         }

        // create the Help menu
        menu = new JMenu("Help");
        menubar.add(menu);
     
        item = new JMenuItem("About ImageViewer...");
            item.addActionListener(new ActionListener() {
                               public void actionPerformed(ActionEvent e) { showAbout(); }
                           });
        menu.add(item);
    }
}

ImagePanel
import java.awt.*;
import javax.swing.*;
import java.awt.image.*;

/**
 * ImagePanel merupakan class yang akan membentuk OFClass
 *
 * @author Satria Ade Veda Karuniawan
 * @version 3.0
 */
public class ImagePanel extends JComponent
{
    // The current width and height of this panel
    private int width, height;

    // An internal image buffer that is used for painting. For
    // actual display, this image buffer is then copied to screen.
    private OFImage panelImage;

    /**
     * Create a new, empty ImagePanel.
     */
    public ImagePanel()
    {
        width = 360;    // arbitrary size for empty panel
        height = 240;
        panelImage = null;
    }

    /**
     * Set the image that this panel should show.
     *
     * @param image  The image to be displayed.
     */
    public void setImage(OFImage image)
    {
        if(image != null) {
            width = image.getWidth();
            height = image.getHeight();
            panelImage = image;
            repaint();
        }
    }
 
    /**
     * Clear the image on this panel.
     */
    public void clearImage()
    {
        Graphics imageGraphics = panelImage.getGraphics();
        imageGraphics.setColor(Color.LIGHT_GRAY);
        imageGraphics.fillRect(0, 0, width, height);
        repaint();
    }
 
    // The following methods are redefinitions of methods
    // inherited from superclasses.
 
    /**
     * Tell the layout manager how big we would like to be.
     * (This method gets called by layout managers for placing
     * the components.)
     *
     * @return The preferred dimension for this component.
     */
    public Dimension getPreferredSize()
    {
        return new Dimension(width, height);
    }
 
    /**
     * This component needs to be redisplayed. Copy the internal image
     * to screen. (This method gets called by the Swing screen painter
     * every time it want this component displayed.)
     *
     * @param g The graphics context that can be used to draw on this component.
     */
    public void paintComponent(Graphics g)
    {
        Dimension size = getSize();
        g.clearRect(0, 0, size.width, size.height);
        if(panelImage != null) {
            g.drawImage(panelImage, 0, 0, null);
        }
    }
}

ImageFileManager
import java.awt.image.*;
import javax.imageio.*;
import java.io.*;

/**
 * ImageFileManager class berfungsi untuk class yang mengatur file-handling
 *
 * Format file : .jpg, .png
 * Variable pengatur : IMAGE_FORMAT
 *
 *
 * @author Satria Ade Veda Karuniawan
 * @version 3.0
 */
public class ImageFileManager
{
    // A constant for the image format that this writer uses for writing.
    // Available formats are "jpg" and "png".
    private static final String IMAGE_FORMAT = "jpg";
 
    /**
     * Read an image file from disk and return it as an image. This method
     * can read JPG and PNG file formats. In case of any problem (e.g the file
     * does not exist, is in an undecodable format, or any other read error)
     * this method returns null.
     *
     * @param imageFile  The image file to be loaded.
     * @return           The image object or null is it could not be read.
     */
    public static OFImage loadImage(File imageFile)
    {
        try {
            BufferedImage image = ImageIO.read(imageFile);
            if(image == null || (image.getWidth(null) < 0)) {
                // we could not load the image - probably invalid file format
                return null;
            }
            return new OFImage(image);
        }
        catch(IOException exc) {
            return null;
        }
    }

    /**
     * Write an image file to disk. The file format is JPG. In case of any
     * problem the method just silently returns.
     *
     * @param image  The image to be saved.
     * @param file   The file to save to.
     */
    public static void saveImage(OFImage image, File file)
    {
        try {
            ImageIO.write(image, IMAGE_FORMAT, file);
        }
        catch(IOException exc) {
            return;
        }
    }
}

OFImage
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;

/**
 * OFImage class yang mendefinisikan sebuah format OF (Objects First).
 *
 * @author Satria Ade Veda Karuniawan
 * @version 3.0
 */
public class OFImage extends BufferedImage
{
    /**
     * Create an OFImage copied from a BufferedImage.
     * @param image The image to copy.
     */
    public OFImage(BufferedImage image)
    {
         super(image.getColorModel(), image.copyData(null),
               image.isAlphaPremultiplied(), null);
    }

    /**
     * Create an OFImage with specified size and unspecified content.
     * @param width The width of the image.
     * @param height The height of the image.
     */
    public OFImage(int width, int height)
    {
        super(width, height, TYPE_INT_RGB);
    }

    /**
     * Set a given pixel of this image to a specified color. The
     * color is represented as an (r,g,b) value.
     * @param x The x position of the pixel.
     * @param y The y position of the pixel.
     * @param col The color of the pixel.
     */
    public void setPixel(int x, int y, Color col)
    {
        int pixel = col.getRGB();
        setRGB(x, y, pixel);
    }
 
    /**
     * Get the color value at a specified pixel position.
     * @param x The x position of the pixel.
     * @param y The y position of the pixel.
     * @return The color of the pixel at the given position.
     */
    public Color getPixel(int x, int y)
    {
        int pixel = getRGB(x, y);
        return new Color(pixel);
    }
}

Abstract Class Filter

/**
 * Filter yang mendefinisikan attribute filter pada umumnya.
 *
 * @author Satria Ade Veda Karuniawan
 * @version 3.0
 */
public abstract class Filter
{
    private String name;
   
    //constructor
    public Filter(String name)
    {
        this.name = name;
    }
   
    //Mendapatkan value dari name
    public String getName()
    {
        return name;
    }
   
    //Override class apply untuk mengganti fungsionalitas dari manipulasi gambar
    public abstract void apply(OFImage image);
}

Darker Filter

/**
 * Darker Filter membuat gambar menjadi lebih gelap.
 *
 * @author Satria Ade Veda Karuniawan
 * @version 3.0
 */
public class DarkerFilter extends Filter
{
    public DarkerFilter(String name)
    {
        super(name);
    }
   
    //Memberikan filter
    public void apply(OFImage image)
    {
        int height = image.getHeight();
        int width = image.getWidth();
        for(int y = 0; y < height; y++){
            for(int x = 0; x < width; x++){
                image.setPixel(x, y, image.getPixel(x, y).darker());
            }
        }
    }
}

Lighter Filter
/**
 * Darker Filter membuat gambar menjadi lebih terang.
 *
 * @author Satria Ade Veda Karuniawan
 * @version 3.0
 */
public class LighterFilter extends Filter
{
/**
* Constructor for objects of class LighterFilter.
     * @param name The name of the filter.
*/
public LighterFilter(String name)
    {
        super(name);
}

    /**
     * Apply this filter to an image.
     *
     * @param  image  The image to be changed by this filter.
     */
    public void apply(OFImage image)
    {
        int height = image.getHeight();
        int width = image.getWidth();
        for(int y = 0; y < height; y++) {
            for(int x = 0; x < width; x++) {
                image.setPixel(x, y, image.getPixel(x, y).brighter());
            }
        }
    }

}

Threshold Filter
import java.awt.Color;

/**
 * Darker Filter membuat gambar menjadi grayscale.
 *
 * @author Satria Ade Veda Karuniawan
 * @version 3.0
 */
public class ThresholdFilter extends Filter
{
/**
* Constructor for objects of class ThresholdFilter.
     * @param name The name of the filter.
*/
public ThresholdFilter(String name)
    {
        super(name);
}

    /**
     * Apply this filter to an image.
     *
     * @param  image  The image to be changed by this filter.
     */
    public void apply(OFImage image)
    {
        int height = image.getHeight();
        int width = image.getWidth();
        for(int y = 0; y < height; y++) {
            for(int x = 0; x < width; x++) {
                Color pixel = image.getPixel(x, y);
                int brightness = (pixel.getRed() + pixel.getBlue() + pixel.getGreen()) / 3;
                if(brightness <= 85) {
                    image.setPixel(x, y, Color.BLACK);
                }
                else if(brightness <= 170) {
                    image.setPixel(x, y, Color.GRAY);
                }
                else {
                    image.setPixel(x, y, Color.WHITE);
                }
            }
        }
    }
}

Fish Eye Filter
import java.awt.Color;

/**
 * Darker Filter membuat gambar menjadi seperti lensa fisheye yang lengkung.
 *
 * @author Satria Ade Veda Karuniawan
 * @version 3.0
 */
public class FishEyeFilter extends Filter
{
    // constants:
    private final static int SCALE = 20;   // this defines the strenght of the filter
    private final static double TWO_PI = 2 * Math.PI;

    /**
     * Constructor for objects of class LensFilter.
     * @param name The name of the filter.
     */
    public FishEyeFilter(String name)
    {
        super(name);
    }

    /**
     * Apply this filter to an image.
     *
     * @param  image  The image to be changed by this filter.
     */
    public void apply(OFImage image)
    {
        int height = image.getHeight();
        int width = image.getWidth();
        OFImage original = new OFImage(image);

        int[] xa = computeXArray(width);
        int[] ya = computeYArray(height);
       
        for(int y = 0; y < height; y++) {
            for(int x = 0; x < width; x++) {
                image.setPixel(x, y, original.getPixel(x + xa[x], y + ya[y]));
            }
        }
    }

    /**
     * Compute and return an array of horizontal offsets for each pixel column.
     * These can then be applied as the horizontal offset for each pixel.
     */
    private int[] computeXArray(int width)
    {
        int[] xArray = new int[width];
       
        for(int i=0; i < width; i++) {
            xArray[i] = (int)(Math.sin( ((double)i / width) * TWO_PI) * SCALE);
        }
        return xArray;
    }

    /**
     * Compute and return an array of vertical offsets for each pixel row.
     * These can then be applied as the vertical offset for each pixel.
     */
    private int[] computeYArray(int height)
    {
        int[] yArray = new int[height];
       
        for(int i=0; i < height; i++) {
            yArray[i] = (int)(Math.sin( ((double)i / height) * TWO_PI) * SCALE);
        }
        return yArray;
    }
}

Simulasi :

  • Load Image
dilakukan dengan cara membuat instance object, File/Open/(directory images)

Original Image Load

  • Smaller

  • Larger



  • Filter Darker

  • Filter Lighter

  • Filter Threshold

  • Filter FishEye



Sekian modifikasi Image Viewer 3.0

Comments

Popular posts from this blog

Technical Support AI

Technical Support - Artificial Intelligence (*From now on, I'll try my best to explain about all of my Project using English) For this project, I made 3 classes to control the Bot Mechanism (Referencing to Objects-First-with-Java-A-Practical-Introduction-Using-BlueJ-David-J-Barnes pages 155) : InputReader Class (Used for detect or to take any user input) SupportSystem Class (As a main function connecting the user input and database) Responder Class (Handling AI-Output and Its role as 'mini' database) Current Version : 1.2 In the future, I'm expecting to have a bigger Responder's Database and would be separated from the Class itself, so it will be easier to make some modification inside the AI's Database and easier to manage. And then i'll try to improve the UX Design inside, so that the user can have a feeling about how 'Human' this AI. InputReader Class In this class, pretty much the same as how the name of the class is writt

University Database System

Implementasi sebuah sistem database dengan menggunakan OOP dan disertai oleh File Handling, terdapat 8 rancangan class : Database (Class yang memiliki kemiripan dengan CRUD system) MainMenu (Menu utama tempat user berinteraksi) PeminjamanBuku (Class Peminjaman yang dapat dimodifikasi) MataKuliah (Class MataKuliah yang dapat dimodifikasi) Orang (Class yang menjadi parent dari Pegawai, Dosen, Mahasiswa) Pegawai Dosen Mahasiswa Source Code (*yang dicantumkan adalah source code inti, source code yang sifatnya dinamis. Selain Database, MainMenu, Orang, PeminjamanBuku, dan MataKuliah) Database import java.io.File; import java.io.IOException; import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.FileReader; import java.io.BufferedReader; import java.util.Scanner; /**  *  *  * @author Satria Ade Veda Karuniawan  * @version 0.1  */ public class Database {     public Database()     {     }         public void Add(String text, Str

Image Viewer GUI

Implementasi Object-Oriented Programming dari Image Viewer yang berfungsi untuk melakukan load sebuah gambar dan memungkinkan dilakukannya manipulasi gambar. Library Java yang digunakan dalam project ini antara lain : Awt (Event, Image) Swing File IO Class yang diimplementasikan antara lain : ImageViewer (Sebagai main class yang melakukan display image pada aplikasi GUI) ImagePanel (Sebagai class yang menampilkan OFImage serta menambah functionality) ImageFileManager (Sebagai class utility untuk melakukan load image) OFImage (Sebagai class yang mendefinisikan image sebagai object) Source Code ImageViewer import java.awt.*; import java.awt.event.*; import java.awt.image.*; import javax.swing.*; import java.io.File; /**  *  * @author Satria Ade Veda Karuniawan  * @version 1.0  */ public class ImageViewer {     // static fields:     private static final String VERSION = "Version 1.0";     private static JFileChooser fileChooser = new JFi