Sunday, December 2, 2018

Tugas PBO A - Image Viewer 3.0

Nama : Haikal Almaz Said
NRP   : 05111740000068
Kelas  : PBO A

Source Code

  • ImageViewer

1:   import java.awt.*;   
2:   import java.awt.event.*;   
3:   import java.awt.image.*;   
4:   import javax.swing.*;   
5:   import javax.swing.border.*;   
6:   import java.io.File;   
7:   import java.util.List;   
8:   import java.util.ArrayList;   
9:   import java.util.Iterator;   
10:   public class ImageViewer   
11:   {   
12:    // static fields:   
13:    private static final String VERSION = "Version 3.0";   
14:    private static JFileChooser fileChooser = new JFileChooser(System.getProperty("user.dir"));   
15:    // fields:   
16:    private JFrame frame;   
17:    private ImagePanel imagePanel;   
18:    private JLabel filenameLabel;   
19:    private JLabel statusLabel;   
20:    private JButton smallerButton;   
21:    private JButton largerButton;   
22:    private OFImage currentImage;   
23:    private List<Filter> filters;   
24:    /**   
25:    * Create an ImageViewer and display its GUI on screen.   
26:    */   
27:    public ImageViewer()   
28:    {   
29:     currentImage = null;   
30:     filters = createFilters();   
31:     makeFrame();   
32:    }   
33:    // ---- implementation of menu functions ----   
34:    /**   
35:    * Open function: open a file chooser to select a new image file,   
36:    * and then display the chosen image.   
37:    */   
38:    private void openFile()   
39:    {   
40:     int returnVal = fileChooser.showOpenDialog(frame);    
41:     if(returnVal != JFileChooser.APPROVE_OPTION) {   
42:      return; // cancelled   
43:     }   
44:     File selectedFile = fileChooser.getSelectedFile();   
45:     currentImage = ImageFileManager.loadImage(selectedFile);   
46:     if(currentImage == null) { // image file was not a valid image   
47:      JOptionPane.showMessageDialog(frame,   
48:        "The file was not in a recognized image file format.",   
49:        "Image Load Error",   
50:        JOptionPane.ERROR_MESSAGE);   
51:      return;   
52:     }   
53:     imagePanel.setImage(currentImage);   
54:     setButtonsEnabled(true);   
55:     showFilename(selectedFile.getPath());   
56:     showStatus("File loaded.");   
57:     frame.pack();   
58:    }   
59:    /**   
60:    * Close function: close the current image.   
61:    */   
62:    private void close()   
63:    {   
64:     currentImage = null;   
65:     imagePanel.clearImage();   
66:     showFilename(null);   
67:     setButtonsEnabled(false);   
68:    }   
69:    /**   
70:    * Save As function: save the current image to a file.   
71:    */   
72:    private void saveAs()   
73:    {   
74:     if(currentImage != null) {   
75:      int returnVal = fileChooser.showSaveDialog(frame);   
76:      if(returnVal != JFileChooser.APPROVE_OPTION) {   
77:       return; // cancelled   
78:      }   
79:      File selectedFile = fileChooser.getSelectedFile();   
80:      ImageFileManager.saveImage(currentImage, selectedFile);   
81:      showFilename(selectedFile.getPath());   
82:     }   
83:    }   
84:    /**   
85:    * Quit function: quit the application.   
86:    */   
87:    private void quit()   
88:    {   
89:     System.exit(0);   
90:    }   
91:    /**   
92:    * Apply a given filter to the current image.   
93:    *    
94:    * @param filter The filter object to be applied.   
95:    */   
96:    private void applyFilter(Filter filter)   
97:    {   
98:     if(currentImage != null) {   
99:      filter.apply(currentImage);   
100:      frame.repaint();   
101:      showStatus("Applied: " + filter.getName());   
102:     }   
103:     else {   
104:      showStatus("No image loaded.");   
105:     }   
106:    }   
107:    /**   
108:    * 'About' function: show the 'about' box.   
109:    */   
110:    private void showAbout()   
111:    {   
112:     JOptionPane.showMessageDialog(frame,    
113:        "ImageViewer\n" + VERSION,   
114:        "About ImageViewer",    
115:        JOptionPane.INFORMATION_MESSAGE);   
116:    }   
117:    /**   
118:    * Make the current picture larger.   
119:    */   
120:    private void makeLarger()   
121:    {   
122:     if(currentImage != null) {   
123:      // create new image with double size   
124:      int width = currentImage.getWidth();   
125:      int height = currentImage.getHeight();   
126:      OFImage newImage = new OFImage(width * 2, height * 2);   
127:      // copy pixel data into new image   
128:      for(int y = 0; y < height; y++) {   
129:       for(int x = 0; x < width; x++) {   
130:        Color col = currentImage.getPixel(x, y);   
131:        newImage.setPixel(x * 2, y * 2, col);   
132:        newImage.setPixel(x * 2 + 1, y * 2, col);   
133:        newImage.setPixel(x * 2, y * 2 + 1, col);   
134:        newImage.setPixel(x * 2+1, y * 2 + 1, col);   
135:       }   
136:      }   
137:      currentImage = newImage;   
138:      imagePanel.setImage(currentImage);   
139:      frame.pack();   
140:     }   
141:    }   
142:    /**   
143:    * Make the current picture smaller.   
144:    */   
145:    private void makeSmaller()   
146:    {   
147:     if(currentImage != null) {   
148:      // create new image with double size   
149:      int width = currentImage.getWidth() / 2;   
150:      int height = currentImage.getHeight() / 2;   
151:      OFImage newImage = new OFImage(width, height);   
152:      // copy pixel data into new image   
153:      for(int y = 0; y < height; y++) {   
154:       for(int x = 0; x < width; x++) {   
155:        newImage.setPixel(x, y, currentImage.getPixel(x * 2, y * 2));   
156:       }   
157:      }   
158:      currentImage = newImage;   
159:      imagePanel.setImage(currentImage);   
160:      frame.pack();   
161:     }   
162:    }   
163:    // ---- support methods ----   
164:    /**   
165:    * Show the file name of the current image in the fils display label.   
166:    * 'null' may be used as a parameter if no file is currently loaded.   
167:    *    
168:    * @param filename The file name to be displayed, or null for 'no file'.   
169:    */   
170:    private void showFilename(String filename)   
171:    {   
172:     if(filename == null) {   
173:      filenameLabel.setText("No file displayed.");   
174:     }   
175:     else {   
176:      filenameLabel.setText("File: " + filename);   
177:     }   
178:    }   
179:    /**   
180:    * Show a message in the status bar at the bottom of the screen.   
181:    * @param text The message to be displayed.   
182:    */   
183:    private void showStatus(String text)   
184:    {   
185:     statusLabel.setText(text);   
186:    }   
187:    /**   
188:    * Enable or disable all toolbar buttons.   
189:    *    
190:    * @param status 'true' to enable the buttons, 'false' to disable.   
191:    */   
192:    private void setButtonsEnabled(boolean status)   
193:    {   
194:     smallerButton.setEnabled(status);   
195:     largerButton.setEnabled(status);   
196:    }   
197:    /**   
198:    * Create a list with all the known filters.   
199:    * @return The list of filters.   
200:    */   
201:    private List<Filter> createFilters()   
202:    {   
203:     List<Filter> filterList = new ArrayList<Filter>();   
204:     filterList.add(new DarkerFilter("Darker"));   
205:     filterList.add(new LighterFilter("Lighter"));   
206:     filterList.add(new ThresholdFilter("Threshold"));   
207:     filterList.add(new FishEyeFilter("Fish Eye"));   
208:     return filterList;   
209:    }   
210:    // ---- swing stuff to build the frame and all its components ----   
211:    /**   
212:    * Create the Swing frame and its content.   
213:    */   
214:    private void makeFrame()   
215:    {   
216:     frame = new JFrame("ImageViewer");   
217:     JPanel contentPane = (JPanel)frame.getContentPane();   
218:     contentPane.setBorder(new EmptyBorder(6, 6, 6, 6));   
219:     makeMenuBar(frame);   
220:     // Specify the layout manager with nice spacing   
221:     contentPane.setLayout(new BorderLayout(6, 6));   
222:     // Create the image pane in the center   
223:     imagePanel = new ImagePanel();   
224:     imagePanel.setBorder(new EtchedBorder());   
225:     contentPane.add(imagePanel, BorderLayout.CENTER);   
226:     // Create two labels at top and bottom for the file name and status message   
227:     filenameLabel = new JLabel();   
228:     contentPane.add(filenameLabel, BorderLayout.NORTH);   
229:     statusLabel = new JLabel(VERSION);   
230:     contentPane.add(statusLabel, BorderLayout.SOUTH);   
231:     // Create the toolbar with the buttons   
232:     JPanel toolbar = new JPanel();   
233:     toolbar.setLayout(new GridLayout(0, 1));   
234:     smallerButton = new JButton("Smaller");   
235:     smallerButton.addActionListener(new ActionListener() {   
236:           public void actionPerformed(ActionEvent e) { makeSmaller(); }   
237:          });   
238:     toolbar.add(smallerButton);   
239:     largerButton = new JButton("Larger");   
240:     largerButton.addActionListener(new ActionListener() {   
241:           public void actionPerformed(ActionEvent e) { makeLarger(); }   
242:          });   
243:     toolbar.add(largerButton);   
244:     // Add toolbar into panel with flow layout for spacing   
245:     JPanel flow = new JPanel();   
246:     flow.add(toolbar);   
247:     contentPane.add(flow, BorderLayout.WEST);   
248:     // building is done - arrange the components     
249:     showFilename(null);   
250:     setButtonsEnabled(false);   
251:     frame.pack();   
252:     // place the frame at the center of the screen and show   
253:     Dimension d = Toolkit.getDefaultToolkit().getScreenSize();   
254:     frame.setLocation(d.width/2 - frame.getWidth()/2, d.height/2 - frame.getHeight()/2);   
255:     frame.setVisible(true);   
256:    }   
257:    /**   
258:    * Create the main frame's menu bar.   
259:    *    
260:    * @param frame The frame that the menu bar should be added to.   
261:    */   
262:    private void makeMenuBar(JFrame frame)   
263:    {   
264:     final int SHORTCUT_MASK =   
265:      Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();   
266:     JMenuBar menubar = new JMenuBar();   
267:     frame.setJMenuBar(menubar);   
268:     JMenu menu;   
269:     JMenuItem item;   
270:     // create the File menu   
271:     menu = new JMenu("File");   
272:     menubar.add(menu);   
273:     item = new JMenuItem("Open...");   
274:      item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, SHORTCUT_MASK));   
275:      item.addActionListener(new ActionListener() {   
276:           public void actionPerformed(ActionEvent e) { openFile(); }   
277:          });   
278:     menu.add(item);   
279:     item = new JMenuItem("Close");   
280:      item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W, SHORTCUT_MASK));   
281:      item.addActionListener(new ActionListener() {   
282:           public void actionPerformed(ActionEvent e) { close(); }   
283:          });   
284:     menu.add(item);   
285:     menu.addSeparator();   
286:     item = new JMenuItem("Save As...");   
287:      item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, SHORTCUT_MASK));   
288:      item.addActionListener(new ActionListener() {   
289:           public void actionPerformed(ActionEvent e) { saveAs(); }   
290:          });   
291:     menu.add(item);   
292:     menu.addSeparator();   
293:     item = new JMenuItem("Quit");   
294:      item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, SHORTCUT_MASK));   
295:      item.addActionListener(new ActionListener() {   
296:           public void actionPerformed(ActionEvent e) { quit(); }   
297:          });   
298:     menu.add(item);   
299:     // create the Filter menu   
300:     menu = new JMenu("Filter");   
301:     menubar.add(menu);   
302:     for(final Filter filter : filters) {   
303:      item = new JMenuItem(filter.getName());   
304:      item.addActionListener(new ActionListener() {   
305:           public void actionPerformed(ActionEvent e) {    
306:            applyFilter(filter);   
307:           }   
308:          });   
309:      menu.add(item);   
310:     }   
311:     // create the Help menu   
312:     menu = new JMenu("Help");   
313:     menubar.add(menu);   
314:     item = new JMenuItem("About ImageViewer...");   
315:      item.addActionListener(new ActionListener() {   
316:           public void actionPerformed(ActionEvent e) { showAbout(); }   
317:          });   
318:     menu.add(item);   
319:    }   
320:   }   

  • ImageFileManager

1:   import java.awt.image.*;   
2:   import javax.imageio.*;   
3:   import java.io.*;   
4:   public class ImageFileManager   
5:   {   
6:    // A constant for the image format that this writer uses for writing.   
7:    // Available formats are "jpg" and "png".   
8:    private static final String IMAGE_FORMAT = "jpg";   
9:    /**   
10:    * Read an image file from disk and return it as an image. This method   
11:    * can read JPG and PNG file formats. In case of any problem (e.g the file    
12:    * does not exist, is in an undecodable format, or any other read error)    
13:    * this method returns null.   
14:    *    
15:    * @param imageFile The image file to be loaded.   
16:    * @return   The image object or null is it could not be read.   
17:    */   
18:    public static OFImage loadImage(File imageFile)   
19:    {   
20:     try {   
21:      BufferedImage image = ImageIO.read(imageFile);   
22:      if(image == null || (image.getWidth(null) < 0)) {   
23:       // we could not load the image - probably invalid file format   
24:       return null;   
25:      }   
26:      return new OFImage(image);   
27:     }   
28:     catch(IOException exc) {   
29:      return null;   
30:     }   
31:    }   
32:    /**   
33:    * Write an image file to disk. The file format is JPG. In case of any    
34:    * problem the method just silently returns.   
35:    *    
36:    * @param image The image to be saved.   
37:    * @param file The file to save to.   
38:    */   
39:    public static void saveImage(OFImage image, File file)   
40:    {   
41:     try {   
42:      ImageIO.write(image, IMAGE_FORMAT, file);   
43:     }   
44:     catch(IOException exc) {   
45:      return;   
46:     }   
47:    }   
48:   }   

  • ImagePanel

1:   import java.awt.*;   
2:   import javax.swing.*;   
3:   import java.awt.image.*;   
4:   public class ImagePanel extends JComponent   
5:   {   
6:    // The current width and height of this panel   
7:    private int width, height;   
8:    // An internal image buffer that is used for painting. For   
9:    // actual display, this image buffer is then copied to screen.   
10:    private OFImage panelImage;   
11:    /**   
12:    * Create a new, empty ImagePanel.   
13:    */   
14:    public ImagePanel()   
15:    {   
16:     width = 360; // arbitrary size for empty panel   
17:     height = 240;   
18:     panelImage = null;   
19:    }   
20:    /**   
21:    * Set the image that this panel should show.   
22:    *    
23:    * @param image The image to be displayed.   
24:    */   
25:    public void setImage(OFImage image)   
26:    {   
27:     if(image != null) {   
28:      width = image.getWidth();   
29:      height = image.getHeight();   
30:      panelImage = image;   
31:      repaint();   
32:     }   
33:    }   
34:    /**   
35:    * Clear the image on this panel.   
36:    */   
37:    public void clearImage()   
38:    {   
39:     Graphics imageGraphics = panelImage.getGraphics();   
40:     imageGraphics.setColor(Color.LIGHT_GRAY);   
41:     imageGraphics.fillRect(0, 0, width, height);   
42:     repaint();   
43:    }   
44:    // The following methods are redefinitions of methods   
45:    // inherited from superclasses.   
46:    /**   
47:    * Tell the layout manager how big we would like to be.   
48:    * (This method gets called by layout managers for placing   
49:    * the components.)   
50:    *    
51:    * @return The preferred dimension for this component.   
52:    */   
53:    public Dimension getPreferredSize()   
54:    {   
55:     return new Dimension(width, height);   
56:    }   
57:    /**   
58:    * This component needs to be redisplayed. Copy the internal image    
59:    * to screen. (This method gets called by the Swing screen painter    
60:    * every time it want this component displayed.)   
61:    *    
62:    * @param g The graphics context that can be used to draw on this component.   
63:    */   
64:    public void paintComponent(Graphics g)   
65:    {   
66:     Dimension size = getSize();   
67:     g.clearRect(0, 0, size.width, size.height);   
68:     if(panelImage != null) {   
69:      g.drawImage(panelImage, 0, 0, null);   
70:     }   
71:    }   
72:   }   

  • OFImage

1:   import java.awt.*;   
2:   import java.awt.image.*;   
3:   import javax.swing.*;   
4:   public class OFImage extends BufferedImage   
5:   {   
6:    /**   
7:    * Create an OFImage copied from a BufferedImage.   
8:    * @param image The image to copy.   
9:    */   
10:    public OFImage(BufferedImage image)   
11:    {   
12:     super(image.getColorModel(), image.copyData(null),    
13:       image.isAlphaPremultiplied(), null);   
14:    }   
15:    /**   
16:    * Create an OFImage with specified size and unspecified content.   
17:    * @param width The width of the image.   
18:    * @param height The height of the image.   
19:    */   
20:    public OFImage(int width, int height)   
21:    {   
22:     super(width, height, TYPE_INT_RGB);   
23:    }   
24:    /**   
25:    * Set a given pixel of this image to a specified color. The   
26:    * color is represented as an (r,g,b) value.   
27:    * @param x The x position of the pixel.   
28:    * @param y The y position of the pixel.   
29:    * @param col The color of the pixel.   
30:    */   
31:    public void setPixel(int x, int y, Color col)   
32:    {   
33:     int pixel = col.getRGB();   
34:     setRGB(x, y, pixel);   
35:    }   
36:    /**   
37:    * Get the color value at a specified pixel position.   
38:    * @param x The x position of the pixel.   
39:    * @param y The y position of the pixel.   
40:    * @return The color of the pixel at the given position.   
41:    */   
42:    public Color getPixel(int x, int y)   
43:    {   
44:     int pixel = getRGB(x, y);   
45:     return new Color(pixel);   
46:    }   
47:   }   

  • Filter

1:   public abstract class Filter   
2:   {   
3:    private String name;   
4:    /**   
5:    * Create a new filter with a given name.   
6:    * @param name The name of the filter.   
7:    */   
8:    public Filter(String name)   
9:    {   
10:     this.name = name;   
11:    }   
12:    /**   
13:    * Return the name of this filter.   
14:    *    
15:    * @return The name of this filter.   
16:    */   
17:    public String getName()   
18:    {   
19:     return name;   
20:    }   
21:    /**   
22:    * Apply this filter to an image.   
23:    *    
24:    * @param image The image to be changed by this filter.   
25:    */   
26:    public abstract void apply(OFImage image);   
27:   }   

  • DarkerFilter

1:   public class DarkerFilter extends Filter   
2:   {   
3:    /**   
4:    * Constructor for objects of class DarkerFilter.   
5:    * @param name The name of the filter.   
6:    */   
7:    public DarkerFilter(String name)   
8:    {   
9:     super(name);   
10:    }   
11:    /**   
12:    * Apply this filter to an image.   
13:    *    
14:    * @param image The image to be changed by this filter.   
15:    */   
16:    public void apply(OFImage image)   
17:    {   
18:     int height = image.getHeight();   
19:     int width = image.getWidth();   
20:     for(int y = 0; y < height; y++) {   
21:      for(int x = 0; x < width; x++) {   
22:       image.setPixel(x, y, image.getPixel(x, y).darker());   
23:      }   
24:     }   
25:    }   
26:   }   

  • LighterFilter

1:   public class LighterFilter extends Filter   
2:   {   
3:     /**   
4:      * Constructor for objects of class LighterFilter.   
5:    * @param name The name of the filter.   
6:      */   
7:     public LighterFilter(String name)   
8:    {   
9:     super(name);   
10:     }   
11:    /**   
12:    * Apply this filter to an image.   
13:    *    
14:    * @param image The image to be changed by this filter.   
15:    */   
16:    public void apply(OFImage image)   
17:    {   
18:     int height = image.getHeight();   
19:     int width = image.getWidth();   
20:     for(int y = 0; y < height; y++) {   
21:      for(int x = 0; x < width; x++) {   
22:       image.setPixel(x, y, image.getPixel(x, y).brighter());   
23:      }   
24:     }   
25:    }   
26:   }   

  • ThresholdFilter

1:   import java.awt.Color;  
2:   public class ThresholdFilter extends Filter   
3:   {   
4:     /**   
5:      * Constructor for objects of class ThresholdFilter.   
6:    * @param name The name of the filter.   
7:      */   
8:     public ThresholdFilter(String name)   
9:    {   
10:     super(name);   
11:     }   
12:    /**   
13:    * Apply this filter to an image.   
14:    *    
15:    * @param image The image to be changed by this filter.   
16:    */   
17:    public void apply(OFImage image)   
18:    {   
19:     int height = image.getHeight();   
20:     int width = image.getWidth();   
21:     for(int y = 0; y < height; y++) {   
22:      for(int x = 0; x < width; x++) {   
23:       Color pixel = image.getPixel(x, y);   
24:       int brightness = (pixel.getRed() + pixel.getBlue() + pixel.getGreen()) / 3;   
25:       if(brightness <= 85) {   
26:        image.setPixel(x, y, Color.BLACK);   
27:       }   
28:       else if(brightness <= 170) {   
29:        image.setPixel(x, y, Color.GRAY);   
30:       }   
31:       else {   
32:        image.setPixel(x, y, Color.WHITE);   
33:       }   
34:      }   
35:     }   
36:    }   
37:   }   

  • FishEyeFilter

1:   import java.awt.Color;   
2:   public class FishEyeFilter extends Filter   
3:   {   
4:    // constants:   
5:    private final static int SCALE = 20; // this defines the strenght of the filter   
6:    private final static double TWO_PI = 2 * Math.PI;   
7:    /**   
8:    * Constructor for objects of class LensFilter.   
9:    * @param name The name of the filter.   
10:    */   
11:    public FishEyeFilter(String name)   
12:    {   
13:     super(name);   
14:    }   
15:    /**   
16:    * Apply this filter to an image.   
17:    *    
18:    * @param image The image to be changed by this filter.   
19:    */   
20:    public void apply(OFImage image)   
21:    {   
22:     int height = image.getHeight();   
23:     int width = image.getWidth();   
24:     OFImage original = new OFImage(image);   
25:     int[] xa = computeXArray(width);   
26:     int[] ya = computeYArray(height);   
27:     for(int y = 0; y < height; y++) {   
28:      for(int x = 0; x < width; x++) {   
29:       image.setPixel(x, y, original.getPixel(x + xa[x], y + ya[y]));   
30:      }   
31:     }   
32:    }   
33:    /**   
34:    * Compute and return an array of horizontal offsets for each pixel column.   
35:    * These can then be applied as the horizontal offset for each pixel.   
36:    */   
37:    private int[] computeXArray(int width)   
38:    {   
39:     int[] xArray = new int[width];   
40:     for(int i=0; i < width; i++) {   
41:      xArray[i] = (int)(Math.sin( ((double)i / width) * TWO_PI) * SCALE);   
42:     }   
43:     return xArray;   
44:    }   
45:    /**   
46:    * Compute and return an array of vertical offsets for each pixel row.   
47:    * These can then be applied as the vertical offset for each pixel.   
48:    */   
49:    private int[] computeYArray(int height)   
50:    {   
51:     int[] yArray = new int[height];   
52:     for(int i=0; i < height; i++) {   
53:      yArray[i] = (int)(Math.sin( ((double)i / height) * TWO_PI) * SCALE);   
54:     }   
55:     return yArray;   
56:    }   
57:   }   



Screenshot






No comments:

Post a Comment