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: }
No comments:
Post a Comment