ImageViewer with BlueJ

Pada Kali ini saya akan membuat Sebuah Image Viewer 3.0. Class-class nya adalah ImageViewer, ImagePanel, ImageFileManager, OFImage (Objects First Image), Filter, ThresholfFilter, LighterFilter, DarkerFilter, dan FishEyeFilter
 








Sourcecodes

Class 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.   
  * @version 3.0   
  */   
 public class ImageViewer   
 {  
   // static fields:   
   private static final String VERSION = "Version 3.0";   
   private static JFileChooser fileChooser = new JFileChooser(System.getProperty("user.dir"));   
   // fields:   
   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);   
   }   
 }

Class 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.   
  * @ver 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);}
} }
Class 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.   
  * @ver 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;}   
   }   
 }

Class OFImage
import java.awt.*;   
 import java.awt.image.*;   
 import javax.swing.*;   
 /**   
  * OFImage is a class that defines an image in OF (Objects First) format.   
  * @ver 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);   
   }   
 }

Class Filter
/**   
  * Filter is an abstract superclass for all image filters in this   
  * application. Filters can be applied to OFImages by invoking the apply    
  * method.   
  * @ver 3.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);   
 }   /**   
  * Filter is an abstract superclass for all image filters in this   
  * application. Filters can be applied to OFImages by invoking the apply    
  * method.   
  * @ver 3.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);   
 }

Class Threshold Filter
import java.awt.Color;   
 /**   
  * An three-level gray-based threshold filter.   
   * @ver 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);}   
        }   
      }   
    }   
 }

Class Lighter Filter
/**   
  * An image filter to make the image a bit lighter.   
  * @ver 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());}   
     }   
   }   
 }

Class Darker Filter
/**   
  * An image filter to make the image a bit darker.   
  * @ver 3.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());}   
     }   
   }   
 }

Class FishEyeFilter
import java.awt.Color;   
 /**   
  * An image filter to create an effect similar to a fisheye camera lens.   
  * (Works especially well on portraits.)   
  * @ver 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;   
   }   
 }

Komentar

Postingan Populer