Skip to main content

Image Viewer GUI 4.0 (Final Exam Project)

Rancangan Interface (Workspace)
Project lanjutan dari Image Viewer GUI 3.0 dengan implementasi menggunakan BlueJ, hal yang telah selesai diimplementasikan adalah :

  • Frame
  • Panel
  • Button
  • Label
  • dll
Dengan daftar class utama sebagai berikut :
  • ImageViewer : merupakan class utama yang berfungsi untuk menampilkan dan menginisialisasi GUI (main class)
  • OFImage : merupakan class yang mendefinisikan objek dari gambar
  • ImagePanel : merupakan class yang salah satunya bertindak sebagai canvas gambar (berbeda dengan ImageViewer, ImagePanel hanya mengatur bagian panel foto saja)
  • ImageFileManager : merupakan class yang bertindak sebagai file handler
Dengan daftar inherited class (Filter) sebagai berikut :
  • DarkerFilter : class Filter yang berfungsi untuk menggelapkan foto
  • LighterFilter : class Filter yang berfungsi untuk menerangkan foto
  • ThresholdFilter : class Filter yang berfungsi untuk merubah warna foto menjadi 3 tingkatan warna dari grayscale
  • InvertFilter : class Filter yang berfungsi untuk menginvert warna
  • SmoothFilter : class Filter yang berfungsi membuat foto terlihat menjadi lebih halus
  • EdgeFilter : class Filter yang mendeteksi dan melakukan highlight pada bagian tepi garis
  • MirrorFilter : class Filter yang berfungsi untuk mencerminkan foto secara horizontal
  • SolarizeFilter : class Filter yang berfungsi memberi efek solarization pada foto
  • PixelizeFilter : class Filter yang berfungsi menambah pixel pada foto (mengurangi kualitas)
  • GrayScaleFilter : class Filter yang berfungsi untuk menghilangkan warna
  • FishEyeFilter : class Filter yang berfungsi untuk memberikan efek layaknya seperti mata ikan
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;

/**
 * ImageViewer is the main class of the image viewer application. It builds and
 * displays the application GUI and initialises all other components.
 * 
 * To start the application, create an object of this class.
 * 
 * @author  Satria Ade Veda Karuniawan
 * @version 4.0
 */
public class ImageViewer
{
    // static fields:
    private static final String VERSION = "Version 4.0";
    private static JFileChooser fileChooser = new JFileChooser(System.getProperty("user.dir"));

    // fields:
    File previousFile;
    private JFrame frame;
    private ImagePanel imagePanel;
    private JLabel filenameLabel;
    private JLabel statusLabel;
    private JLabel spaceLabel;
    
    private JButton resetButton;
    private JLabel sizeLabel;
    private JButton smallerButton;
    private JButton largerButton;
    
    private JLabel brightnessLabel;
    private JButton filterButton;
    
    private OFImage currentImage;
    private OFImage previousImage;
    
    private List<Filter> filters;
    
    /**
     * Create an ImageViewer and display its GUI on screen.
     */
    public ImageViewer()
    {
        currentImage = null;
        spaceLabel = new JLabel("");
        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();
        previousFile = selectedFile;
        currentImage = ImageFileManager.loadImage(selectedFile);
        //previousImage = 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();
        }
    }
    
    private void resetImage()
    {
        currentImage = ImageFileManager.loadImage(previousFile);
        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 status message.
     */
    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);
        resetButton.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 InvertFilter("Invert"));
        filterList.add(new SolarizeFilter("Solarize"));
        filterList.add(new SmoothFilter("Smooth"));
        filterList.add(new PixelizeFilter("Pixelize"));
        filterList.add(new MirrorFilter("Mirror"));
        filterList.add(new GrayScaleFilter("Grayscale"));
        filterList.add(new EdgeFilter("Edge Detection"));
        filterList.add(new FishEyeFilter("Fish Eye"));
       
        return filterList;
    }
    
    // ---- Swing stuff to build the frame and all its components and menus ----
    
    /**
     * 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 messages
        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));
        
        resetButton = new JButton("Reset");
        resetButton.addActionListener(new ActionListener() {
                               public void actionPerformed(ActionEvent e) { resetImage(); }
                           });
        toolbar.add(resetButton);
        
        toolbar.add(spaceLabel);
        sizeLabel = new JLabel("Size");
        toolbar.add(sizeLabel);
        
        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);
        
        toolbar.add(spaceLabel);
        brightnessLabel = new JLabel("Filter");
        toolbar.add(brightnessLabel);
        
        for(final Filter filter : filters) {
            filterButton = new JButton(filter.getName());
            //filterButton.setEnabled(false);
            filterButton.addActionListener(new ActionListener() {
                                public void actionPerformed(ActionEvent e) { 
                                    applyFilter(filter);
                                }
                           });
             toolbar.add(filterButton);
         }
        
        // 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 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.*;

/**
 * An ImagePanel is a Swing component that can display an OFImage.
 * It is constructed as a subclass of JComponent with the added functionality
 * of setting an OFImage that will be displayed on the surface of this
 * component.
 * 
 * @author  Satria Ade Veda Karuniawan
 * @version 4.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 is a small utility class with static methods to load
 * and save images.
 * 
 * The files on disk can be in JPG or PNG image format. For files written
 * by this class, the format is determined by the constant IMAGE_FORMAT.
 * 
 * @author  Satria Ade Veda Karuniawan
 * @version 4.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 is a class that defines an image in OF (Objects First) format.
 * 
 * @author  Satria Ade Veda Karuniawan
 * @version 4.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) Filter

/**
 * Filter is an abstract superclass for all image filters in this
 * application. Filters can be applied to OFImages by invoking the apply 
 * method.
 * 
 * @author  Satria Ade Veda Karuniawan
 * @version 4.0
 */
public abstract class Filter
{
    private String name;

    /**
     * Create a new filter with a given name.
     * @param name The name of the filter.
     */
    public Filter(String name)
    {
        this.name = name;
    }
    
    /**
     * Return the name of this filter.
     * 
     * @return  The name of this filter.
     */
    public String getName()
    {
        return name;
    }
    
    /**
     * Apply this filter to an image.
     * 
     * @param  image  The image to be changed by this filter.
     */
    public abstract void apply(OFImage image);
}


LighterFilter

/**
 * An image filter to make the image a bit lighter.
 * 
 * @author  Satria Ade Veda Karuniawan
 * @version 4.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());
            }
        }
    }

}


DarkerFilter

/**
 * An image filter to make the image a bit darker.
 * 
 * @author  Satria Ade Veda Karuniawan
 * @version 4.0
 */
public class DarkerFilter extends Filter
{
    /**
     * Constructor for objects of class DarkerFilter.
     * @param name The name of the filter.
     */
    public DarkerFilter(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).darker());
            }
        }
    }
}


ThresholdFilter

import java.awt.Color;

/**
 * An three-level gray-based threshold filter.
 * 
 * @author  Satria Ade Veda Karuniawan
 * @version 4.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);
                }
            }
        }
    }
}


InvertFilter

import java.awt.Color;

/**
 * An image filter to invert colors.
 * 
 * @author  Satria Ade Veda Karuniawan
 * @version 4.0
 */
public class InvertFilter extends Filter
{
    /**
     * Constructor for objects of class InvertFilter.
     * @param name The name of the filter.
     */
    public InvertFilter(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 pix = image.getPixel(x, y);
                image.setPixel(x, y, new Color(255 - pix.getRed(),
                                               255 - pix.getGreen(),
                                               255 - pix.getBlue()));
            }
        }
    }
}


SmoothFilter

import java.awt.Color;
import java.util.List;
import java.util.ArrayList;

/**
 * An image filter to reduce sharp edges and pixelization. A bit like
 * a soft lens.
 * 
 * @author  Satria Ade Veda Karuniawan
 * @version 4.0
 */
public class SmoothFilter extends Filter
{
    private OFImage original;
    private int width;
    private int height;
    
    /**
     * Constructor for objects of class SmoothFilter.
     * @param name The name of the filter.
     */
    public SmoothFilter(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)
    {
        original = new OFImage(image);
        width = original.getWidth();
        height = original.getHeight();
        
        for(int y = 0; y < height; y++) {
            for(int x = 0; x < width; x++) {
                image.setPixel(x, y, smooth(x, y));
            }
        }
    }
    
    /**
     * Return a new color that is the smoothed color of a given
     * position. The "smoothed color" is the color value that is the
     * average of this pixel and all the adjacent pixels.
     * @param xpos The xposition of the pixel.
     * @param ypos The yposition of the pixel.
     * @return The smoothed color.
     */
    private Color smooth(int xpos, int ypos)
    {
        List<Color> pixels = new ArrayList<Color>(9);
        
        for(int y = ypos - 1; y <= ypos + 1; y++) {
            for(int x = xpos - 1; x <= xpos + 1; x++) {
                if( x >= 0 && x < width && y >= 0 && y < height )
                    pixels.add(original.getPixel(x, y));
            }
        }

        return new Color(avgRed(pixels), avgGreen(pixels), avgBlue(pixels));
    }

    /**
     * @param pixels The list of pixels.
     * @return The average of all the red values in the given list of pixels.
     */
    private int avgRed(List<Color> pixels)
    {
        int total = 0;
        for(Color color : pixels) {
            total += color.getRed();
        }
        return total / pixels.size();
    }

    /**
     * @param pixels The list of pixels.
     * @return The average of all the green values in the given list of pixels.
     */
    private int avgGreen(List<Color> pixels)
    {
        int total = 0;
        for(Color color : pixels) {
            total += color.getGreen();
        }
        return total / pixels.size();
    }

    /**
     * @param pixels The list of pixels.
     * @return The average of all the blue values in the given list of pixels.
     */
    private int avgBlue(List<Color> pixels)
    {
        int total = 0;
        for(Color color : pixels) {
            total += color.getBlue();
        }
        return total / pixels.size();
    }
}


EdgeFilter

import java.awt.Color;

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

/**
 * An image filter to detect edges and highlight them, a bit like 
 * a colored pencil drawing.
 * 
 * @author  Satria Ade Veda Karuniawan
 * @version 4.0
 */
public class EdgeFilter extends Filter
{
    private static final int TOLERANCE = 20;
    
    private OFImage original;
    private int width;
    private int height;

    /**
     * Constructor for objects of class EdgeFilter.
     * @param name The name of the filter.
     */
    public EdgeFilter(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)
    {
        original = new OFImage(image);
        width = original.getWidth();
        height = original.getHeight();
        
        for(int y = 0; y < height; y++) {
            for(int x = 0; x < width; x++) {
                image.setPixel(x, y, edge(x, y));
            }
        }
    }

    /**
     * Return a new color that is the smoothed color of a given
     * position. The "smoothed color" is the color value that is the
     * average of this pixel and all the adjacent pixels.
     * @param xpos The x position of the pixel.
     * @param ypos The y position of the pixel.
     * @return The smoothed color.
     */
    private Color edge(int xpos, int ypos)
    {
        List<Color> pixels = new ArrayList<Color>(9);
        
        for(int y = ypos-1; y <= ypos+1; y++) {
            for(int x = xpos-1; x <= xpos+1; x++) {
                if( x >= 0 && x < width && y >= 0 && y < height ) {
                    pixels.add(original.getPixel(x, y));
                }
            }
        }

        return new Color(255 - diffRed(pixels), 255 - diffGreen(pixels), 255 - diffBlue(pixels));
    }

    /**
     * @param pixels The list of pixels to be averaged.
     * @return The average of all the red values in the given list of pixels.
     */
    private int diffRed(List<Color> pixels)
    {
        int max = 0;
        int min = 255;
        for(Color color : pixels) {
            int val = color.getRed();
            if(val > max) {
                max = val;
            }
            if(val < min) {
                min = val;
            }
        }
        int difference = max - min - TOLERANCE;
        if(difference < 0) {
            difference = 0;
        }
        return difference;
    }

    /**
     * @param pixels The list of pixels to be averaged.
     * @return The average of all the green values in the given list of pixels.
     */
    private int diffGreen(List<Color> pixels)
    {
        int max = 0;
        int min = 255;
        for(Color color : pixels) {
            int val = color.getGreen();
            if(val > max) {
                max = val;
            }
            if(val < min) {
                min = val;
            }
        }
        int difference = max - min - TOLERANCE;
        if(difference < 0) {
            difference = 0;
        }
        return difference;
    }

    /**
     * @param pixels The list of pixels to be averaged.
     * @return The average of all the blue values in the given list of pixels.
     */
    private int diffBlue(List<Color> pixels)
    {
        int max = 0;
        int min = 255;
        for(Color color : pixels) {
            int val = color.getBlue();
            if(val > max) {
                max = val;
            }
            if(val < min) {
                min = val;
            }
        }
        int difference = max - min - TOLERANCE;
        if(difference < 0) {
            difference = 0;
        }
        return difference;
    }

}


MirrorFilter

import java.awt.Color;

/**
 * An image filter to mirror (flip) the image horizontally.
 * 
 * @author  Satria Ade Veda Karuniawan
 * @version 4.0
 */
public class MirrorFilter extends Filter
{
 /**
  * Constructor for objects of class MirrorFilter.
     * @param name The name of the filter.
  */
 public MirrorFilter(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 / 2; x++) {
                Color left = image.getPixel(x, y);
                image.setPixel(x, y, image.getPixel(width - 1 - x, y));
                image.setPixel(width - 1 - x, y, left);
            }
        }
    }
}


SolarizeFilter

import java.awt.Color;

/**
 * An image filter to create a solarization effect.
 * 
 * @author  Satria Ade Veda Karuniawan
 * @version 4.0
 */
public class SolarizeFilter extends Filter
{
    /**
     * Constructor for objects of class Solarize.
     * @param name The name of the filter.
     */
    public SolarizeFilter(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 pix = image.getPixel(x, y);
                int red = pix.getRed();
                if(red <= 127) {
                    red = 255 - red;
                }
                int green = pix.getGreen();
                if(green <= 127) {
                    green = 255 - green;
                }
                int blue = pix.getBlue();
                if(blue <= 127) {
                    blue = 255 - blue;
                }
                image.setPixel(x, y, new Color(red, green, blue));
            }
        }
    }

}


PixelizeFilter

import java.awt.Color;

/**
 * An image filter to create a pixelization effect, like an enlarged
 * low-resolution digital image.
 * 
 * @author  Satria Ade Veda Karuniawan
 * @version 4.0
 */
public class PixelizeFilter extends Filter
{
    /**
     * Constructor for objects of class PixelizeFilter.
     * @param name The name of the filter.
     */
    public PixelizeFilter(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)
    {
        final int PIXEL_SIZE = 5;
        int width = image.getWidth();
        int height = image.getHeight();
        
        for(int y = 0; y < height; y += PIXEL_SIZE) {
            for(int x = 0; x < width; x += PIXEL_SIZE) {
                Color pix = image.getPixel(x, y);
                for(int dy = y; dy < y + PIXEL_SIZE; dy++) {
                    for(int dx = x; dx < x + PIXEL_SIZE; dx++) {
                        if( dx < width && dy < height )
                            image.setPixel(dx, dy, pix);
                    }
                }
            }
        }
    }
}


GrayScaleFilter

import java.awt.Color;

/**
 * An image filter to remove color from an image.
 * 
 * @author  Satria Ade Veda Karuniawan
 * @version 4.0
 */
public class GrayScaleFilter extends Filter
{
 /**
  * Constructor for objects of class GrayScaleFilter.
  * @param name The name of the filter.
  */
 public GrayScaleFilter(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 pix = image.getPixel(x, y);
                int avg = (pix.getRed() + pix.getGreen() + pix.getBlue()) / 3;
                image.setPixel(x, y, new Color(avg, avg, avg));
            }
        }
    }
}


FishEyeFilter

import java.awt.Color;

/**
 * An image filter to create an effect similar to a fisheye camera lens.
 * (Works especially well on portraits.)
 * 
 * @author  Satria Ade Veda Karuniawan
 * @version 4.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

  1. Untuk membuka applikasi, silahkan buat Object baru pada ImageViewer
  2. Buka foto pada aplikasi dengan cara membuka File > Open > Directory yang dipilih atau Ctrl + O sebagai shortcut
  3. Uji Coba Function
  • Foto Asli
  • Smaller
  • Larger
  • Darker
  • Lighter
  • Threshold
  • Invert
  • Solarize
  • Smooth
  • Pixelize
  • Mirror
  • Grayscale
  • Edge Detection
  • Fish Eye
  • Reset

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

Fox And Rabbit

Implementasi Fox and Rabbit berupa simulasi hubungan antara predator (dalam hal ini Fox) dan prey (dalam hal ini Rabbit), digunakan 9 class : Simulator (sebagai class utama yang digunakan untuk melakukan simulasi) SimulatorView (sebagai pengatur tampilan yang diimplementasikan pada class Simulator) Field (sebagai class yang mengatur dan memanipulasi bidang simulasi yang telah ditentukan) FieldStats (sebagai class berupa value holder yang menyimpan kondisi dari Field) Counter (sebagai class penghitung seperti increment dan reset value) Location (sebagai class yang memiliki informasi posisi pada Field) Randomizer (sebagai class yang mengatur nilai random) Fox (sebagai class simulator yang bertindak sebagai predator) Rabbit (sebagai class simulator yang bertindak sebagai prey) Source Code Simulator import java.util.Random; import java.util.List; import java.util.ArrayList; import java.util.Iterator; import java.awt.Color; import java.util.concurrent.TimeUnit; impo

Hello World!

Tugas 1 Source Code /**  * Write a description of class Test here.  * Program Data Diri  * @author Satria Ade Veda Karuniawan  * @version 0.1  */ public class Test {     // instance variables - replace the example below with your own         public Test()       {           String nama = "Satria Ade Veda Karuniawan";           String kelas = "PBO A";           String alamat = "Jl. Rajawali 4 no 2 Rewwin Sidoarjo";           String email = "dnaspeedmania@gmail.com";           String blog = "newsavk.blogspot.com";           String nomor = "081615522636";           String twitter = "@SatriaAdeVK2";           System.out.println("Nama          : " + nama);           System.out.println("Kelas         : " + kelas);           System.out.println("Alamat Rumah  : " + alamat);           System.out.println("Email         : " + email);           System.out.printl