Langsung ke konten utama

GUI: Image Viewer V3

Hi guys! In this post, we will make an Image Viewer v3 with GUI Programming.

This is the classes we need to make the program:
  1. ImageViewer
  2. ImagePanel
  3. ImageFileManager
  4. OFImage
  5. Filter
  6. LighterFilter
  7. DarkerFilter
  8. ThresholdFilter
  9. FishEyeFilter
Here is the source code for each of those classes
  • 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  
      * initializes all other components.  
      *  
      * @author (Elkana Hans Widersen)  
      * @version 1.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();  
       }  
       // ---- 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 shortcutMask = 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, shortcutMask));  
         item.addActionListener(new ActionListener() {  
           public void actionPerformed(ActionEvent e) { openFile(); }  
         });  
         menu.add(item);  
         item = new JMenuItem("Close");  
         item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W, shortcutMask));  
         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, shortcutMask));  
         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, shortcutMask));  
         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.*;   
     /**   
      * 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 (Elkana Hans Widersen)  
      * @version 1.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.lightGray);   
         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  
        * wants 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 (Elkana Hans Widersen)  
      * @version 1.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 (Elkana Hans Widersen)   
      * @version 1.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);   
       }   
     }  
    
  • 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 (Elkana Hans Widersen)  
      * @version 1.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. (versi 3.0)  
      *  
      * @author (Elkana Hans Widersen)  
      * @version 1.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. (versi 3.0)  
      *  
      * @author (Elkana Hans Widersen)  
      * @version 1.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. (versi 3.0)  
      *  
      * @author (Elkana Hans Widersen)  
      * @version 1.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);  
           }  
         }  
       }  
     }  
    
  • FishEyeFilter

     import java.awt.Color;  
     /**  
      * An image filter to create an effect similar  
      * to a fisheye camera lens.  
      * (Works especially well on portraits.)  
      *  
      * @author (Elkana Hans Widersen)  
      * @version 1.0  
      */  
     public class FishEyeFilter extends Filter {  
       // constants:  
       private final static int scale = 20;  // this defines the strenght of the filter  
       private final static double doublePi = 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) * doublePi) * 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) * doublePi) * scale);  
         }  
         return yArray;  
       }  
     }  
    
This is how it works:
Step 1:
Right-click on ImageViewer class box and this window will appear.

Step 2:
This window will appear. Next, you need to open an image file. 
For this example, we'll be using my photo.

This is how it looks:

Larger 1x + No Filter

Smaller 1x + Lighter

Smaller 1x + Darker

Smaller 1x + Threshold

Smaller 1x + Fish Eye


Thanks and see you next time!

Komentar

Postingan populer dari blog ini

Fox and Rabbit Simulator

Hi guys! I'm going to show you a Fox and Rabbit Simulator made in BlueJ. We're going to use these classes Simulator SimulatorView Location Field FieldStats Counter Randomizer Rabbit Fox Here is the source code of those classes: Simulator import java.util.Random; import java.util.List; import java.util.ArrayList; import java.util.Iterator; import java.awt.Color; /** * A simple predator-prey simulator, based on a rectangular field * containing rabbits and foxes. * * @author Elkana Hans Widersen * @version 1.0 */ public class Simulator { /** * Constants representing configuration information for the simulation. */ private static final int def_width = 50; // The default width for the grid. private static final int def_depth = 50; // The default depth of the grid. private static final double foxProbability = 0.02; // The probability that a fo...

Tugas 1 PBO A

This is my biodata compiled in Java (first time usage). Check it out! /** * Program membuat biodata menggunakan Java - BlueJ * * Author : Elkana Hans W * Version 1 , Date : 3 September 2018 */ public class biodata{ public biodata(){ System.out.print("PBO-Tugas1\n"); System.out.print("Nama\t: Elkana Hans Widersen\n"); System.out.print("Kelas\t: PBO A\n"); System.out.print("Alamat Rumah: Merak III/P2-104 Rewwin\n"); System.out.print("Email\t: elknhns@gmail.com\n"); System.out.print("Blog\t: elkanahans.blogspot.com\n"); System.out.print("No HP/WA: 082143646716\n"); System.out.print("Twitter\t: @elknhns\n"); } }

Tugas PBO Psychological Support Chatbot

Hi! We're back again! This time I'm going to show you my recent project on making a chatbot for technical support, called Monokuro Boo. It's great for you if you have traumas, problems, distress, etc. I'm using 3 classes for this chatbot, which are: SupportSystem InputReader Responder These are the source code. Check it out! SupportSystem /** * The main class for the support system, consisting greetings template. * * @author (Elkana Hans Widersen) * @version (08.10.2018) */ public class SupportSystem { private InputReader reader; private Responder responder; /** * Creates a technical support system. */ public SupportSystem() { reader = new InputReader(); responder = new Responder(); } /** * Start the technical support system. This will print a * welcome message and enter into a dialog with the user, * until the user ends the dialo...