UAS PBO - ImageViewer
Dari aplikasi ImageViewer yang telah dibuat kembangkan menjadi aplikasi image editor. Aplikasi ini ditambahkan fitur Crop, Rotate, dan tambahan beberapa Filter.
- Gambaran Interface
- Class Diagram
- Filter sebagai abstrak dari semua filter yang ada
- Filter-Filter yang ada memiliki kegunaan sesuai namanya
- OFImage: mendefinisikan sebuah gambar
- ImagePanel: menampilkan OFImage, merupakan komponen swing
- ImageFileManager: membuat dan menyimpan gambar
- ImageViewer: main class dari ImageViewer
Tampilan
Tampilan baru setelah dikembangkan
(Output dari Crop, Rotate, maupun Filter lain tidak saya tampilkan karena ada error dari blogger dimana saya tidak dapat menimpan perubahan postingan ini jika ditambahkan hasil ss tersebut)
(Output dari Crop, Rotate, maupun Filter lain tidak saya tampilkan karena ada error dari blogger dimana saya tidak dapat menimpan perubahan postingan ini jika ditambahkan hasil ss tersebut)
Source Code
EdgeFilter
import java.awt.Color;
import java.util.List;
import java.util.ArrayList;
/**
* An image filter to detect edges and highlight them, a bit like
* a colored pencil drawing.
*
* @author Michael Kolling and David J Barnes
* @version 1.0
*/
public class EdgeFilter extends Filter
{
private static final int TOLERANCE = 20;
private OFImage original;
private int width;
private int height;
/**
* Constructor for objects of class EdgeFilter.
* @param name The name of the filter.
*/
public EdgeFilter(String name)
{
super(name);
}
/**
* Apply this filter to an image.
*
* @param image The image to be changed by this filter.
*/
public void apply(OFImage image)
{
original = new OFImage(image);
width = original.getWidth();
height = original.getHeight();
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
image.setPixel(x, y, edge(x, y));
}
}
}
/**
* Return a new color that is the smoothed color of a given
* position. The "smoothed color" is the color value that is the
* average of this pixel and all the adjacent pixels.
* @param xpos The x position of the pixel.
* @param ypos The y position of the pixel.
* @return The smoothed color.
*/
private Color edge(int xpos, int ypos)
{
List<Color> pixels = new ArrayList<Color>(9);
for(int y = ypos-1; y <= ypos+1; y++) {
for(int x = xpos-1; x <= xpos+1; x++) {
if( x >= 0 && x < width && y >= 0 && y < height ) {
pixels.add(original.getPixel(x, y));
}
}
}
return new Color(255 - diffRed(pixels), 255 - diffGreen(pixels), 255 - diffBlue(pixels));
}
/**
* @param pixels The list of pixels to be averaged.
* @return The average of all the red values in the given list of pixels.
*/
private int diffRed(List<Color> pixels)
{
int max = 0;
int min = 255;
for(Color color : pixels) {
int val = color.getRed();
if(val > max) {
max = val;
}
if(val < min) {
min = val;
}
}
int difference = max - min - TOLERANCE;
if(difference < 0) {
difference = 0;
}
return difference;
}
/**
* @param pixels The list of pixels to be averaged.
* @return The average of all the green values in the given list of pixels.
*/
private int diffGreen(List<Color> pixels)
{
int max = 0;
int min = 255;
for(Color color : pixels) {
int val = color.getGreen();
if(val > max) {
max = val;
}
if(val < min) {
min = val;
}
}
int difference = max - min - TOLERANCE;
if(difference < 0) {
difference = 0;
}
return difference;
}
/**
* @param pixels The list of pixels to be averaged.
* @return The average of all the blue values in the given list of pixels.
*/
private int diffBlue(List<Color> pixels)
{
int max = 0;
int min = 255;
for(Color color : pixels) {
int val = color.getBlue();
if(val > max) {
max = val;
}
if(val < min) {
min = val;
}
}
int difference = max - min - TOLERANCE;
if(difference < 0) {
difference = 0;
}
return difference;
}
}
GrayScaleFilter
import java.awt.Color;
/**
* An image filter to remove color from an image.
*
* @author Michael Kolling and David J Barnes
* @version 1.0
*/
public class GrayScaleFilter extends Filter
{
/**
* Constructor for objects of class GrayScaleFilter.
* @param name The name of the filter.
*/
public GrayScaleFilter(String name)
{
super(name);
}
/**
* Apply this filter to an image.
*
* @param image The image to be changed by this filter.
*/
public void apply(OFImage image)
{
int height = image.getHeight();
int width = image.getWidth();
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
Color pix = image.getPixel(x, y);
int avg = (pix.getRed() + pix.getGreen() + pix.getBlue()) / 3;
image.setPixel(x, y, new Color(avg, avg, avg));
}
}
}
}
InvertFilter
import java.awt.Color;
/**
* An image filter to invert colors.
*
* @author Michael Kolling and David J Barnes
* @version 1.0
*/
public class InvertFilter extends Filter
{
/**
* Constructor for objects of class InvertFilter.
* @param name The name of the filter.
*/
public InvertFilter(String name)
{
super(name);
}
/**
* Apply this filter to an image.
*
* @param image The image to be changed by this filter.
*/
public void apply(OFImage image)
{
int height = image.getHeight();
int width = image.getWidth();
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
Color pix = image.getPixel(x, y);
image.setPixel(x, y, new Color(255 - pix.getRed(),
255 - pix.getGreen(),
255 - pix.getBlue()));
}
}
}
}
MirrorFilter
import java.awt.Color;
/**
* An image filter to mirror (flip) the image horizontally.
*
* @author Michael Kolling and David J Barnes
* @version 1.0
*/
public class MirrorFilter extends Filter
{
/**
* Constructor for objects of class MirrorFilter.
* @param name The name of the filter.
*/
public MirrorFilter(String name)
{
super(name);
}
/**
* Apply this filter to an image.
*
* @param image The image to be changed by this filter.
*/
public void apply(OFImage image)
{
int height = image.getHeight();
int width = image.getWidth();
for(int y = 0; y < height; y++) {
for(int x = 0; x < width / 2; x++) {
Color left = image.getPixel(x, y);
image.setPixel(x, y, image.getPixel(width - 1 - x, y));
image.setPixel(width - 1 - x, y, left);
}
}
}
}
SmoothFilter
import java.awt.Color;
import java.util.List;
import java.util.ArrayList;
/**
* An image filter to reduce sharp edges and pixelization. A bit like
* a soft lens.
*
* @author Michael Kolling and David J Barnes
* @version 1.0
*/
public class SmoothFilter extends Filter
{
private OFImage original;
private int width;
private int height;
/**
* Constructor for objects of class SmoothFilter.
* @param name The name of the filter.
*/
public SmoothFilter(String name)
{
super(name);
}
/**
* Apply this filter to an image.
*
* @param image The image to be changed by this filter.
*/
public void apply(OFImage image)
{
original = new OFImage(image);
width = original.getWidth();
height = original.getHeight();
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
image.setPixel(x, y, smooth(x, y));
}
}
}
/**
* Return a new color that is the smoothed color of a given
* position. The "smoothed color" is the color value that is the
* average of this pixel and all the adjacent pixels.
* @param xpos The xposition of the pixel.
* @param ypos The yposition of the pixel.
* @return The smoothed color.
*/
private Color smooth(int xpos, int ypos)
{
List<Color> pixels = new ArrayList<Color>(9);
for(int y = ypos - 1; y <= ypos + 1; y++) {
for(int x = xpos - 1; x <= xpos + 1; x++) {
if( x >= 0 && x < width && y >= 0 && y < height )
pixels.add(original.getPixel(x, y));
}
}
return new Color(avgRed(pixels), avgGreen(pixels), avgBlue(pixels));
}
/**
* @param pixels The list of pixels.
* @return The average of all the red values in the given list of pixels.
*/
private int avgRed(List<Color> pixels)
{
int total = 0;
for(Color color : pixels) {
total += color.getRed();
}
return total / pixels.size();
}
/**
* @param pixels The list of pixels.
* @return The average of all the green values in the given list of pixels.
*/
private int avgGreen(List<Color> pixels)
{
int total = 0;
for(Color color : pixels) {
total += color.getGreen();
}
return total / pixels.size();
}
/**
* @param pixels The list of pixels.
* @return The average of all the blue values in the given list of pixels.
*/
private int avgBlue(List<Color> pixels)
{
int total = 0;
for(Color color : pixels) {
total += color.getBlue();
}
return total / pixels.size();
}
}
SolarizeFilter
import java.awt.Color;
/**
* An image filter to create a solarization effect.
*
* @author Michael Kolling and David J Barnes
* @version 1.0
*/
public class SolarizeFilter extends Filter
{
/**
* Constructor for objects of class Solarize.
* @param name The name of the filter.
*/
public SolarizeFilter(String name)
{
super(name);
}
/**
* Apply this filter to an image.
*
* @param image The image to be changed by this filter.
*/
public void apply(OFImage image)
{
int height = image.getHeight();
int width = image.getWidth();
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
Color pix = image.getPixel(x, y);
int red = pix.getRed();
if(red <= 127) {
red = 255 - red;
}
int green = pix.getGreen();
if(green <= 127) {
green = 255 - green;
}
int blue = pix.getBlue();
if(blue <= 127) {
blue = 255 - blue;
}
image.setPixel(x, y, new Color(red, green, blue));
}
}
}
}
PixelizaFilter
import java.awt.Color;
/**
* An image filter to create a pixelization effect, like an enlarged
* low-resolution digital image.
*
* @author Michael Kolling and David J Barnes
* @version 1.0
*/
public class PixelizeFilter extends Filter
{
/**
* Constructor for objects of class PixelizeFilter.
* @param name The name of the filter.
*/
public PixelizeFilter(String name)
{
super(name);
}
/**
* Apply this filter to an image.
*
* @param image The image to be changed by this filter.
*/
public void apply(OFImage image)
{
final int PIXEL_SIZE = 5;
int width = image.getWidth();
int height = image.getHeight();
for(int y = 0; y < height; y += PIXEL_SIZE) {
for(int x = 0; x < width; x += PIXEL_SIZE) {
Color pix = image.getPixel(x, y);
for(int dy = y; dy < y + PIXEL_SIZE; dy++) {
for(int dx = x; dx < x + PIXEL_SIZE; dx++) {
if( dx < width && dy < height )
image.setPixel(dx, dy, pix);
}
}
}
}
}
}
ImageViewer update
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import javax.swing.border.*;
import java.io.File;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
/**
* ImageViewer is the main class of the image viewer application. It builds and
* displays the application GUI and initialises all other components.
*
* To start the application, create an object of this class.
*
* @author Michael Kolling and David J Barnes
* @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 JButton cropButton;
private JButton RotateL;
private JButton RotateR;
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);
}
/**
* Rotate the current picture to left.
*/
private void Rotate90left() {
if(currentImage != null) {
// create new image with double size
int width = currentImage.getWidth();
int height = currentImage.getHeight();
OFImage newImage = new OFImage(height, width);
//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(y, width-x-1, col);
}
}
currentImage = newImage;
imagePanel.setImage(currentImage);
frame.pack();
}
}
/**
* Rotate the current picture to right.
*/
private void Rotate90right() {
if(currentImage != null) {
// create new image with double size
int width = currentImage.getWidth();
int height = currentImage.getHeight();
OFImage newImage = new OFImage(height, width);
//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(height-y-1, x, col);
}
}
currentImage = newImage;
imagePanel.setImage(currentImage);
frame.pack();
}
}
/**
* 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();
}
}
/**
* Crop the current image.
*/
private void crop()
{
if (currentImage != null)
{
int width = currentImage.getWidth();
int height = currentImage.getWidth();
int xAwal = Integer.parseInt(JOptionPane.showInputDialog("xAwal"));
int yAwal = Integer.parseInt(JOptionPane.showInputDialog("yAwal"));
int xAkhir = Integer.parseInt(JOptionPane.showInputDialog("xAkhir"));
int yAkhir = Integer.parseInt(JOptionPane.showInputDialog("yAkhir"));
OFImage newImage = new OFImage(xAkhir - xAwal, yAkhir - yAwal);
for (int y = 0; y < yAkhir - yAwal; y++)
{
for (int x = 0; x < xAkhir - xAwal; x++)
{
newImage.setPixel(x, y, currentImage.getPixel(x + xAwal, y + yAwal));
}
}
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);
cropButton.setEnabled(status);
RotateL.setEnabled(status);
RotateR.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"));
filterList.add(new InvertFilter("Invert"));
filterList.add(new SolarizeFilter("Solarize"));
filterList.add(new SmoothFilter("Smooth"));
filterList.add(new PixelizeFilter("Pixelize"));
filterList.add(new MirrorFilter("Mirror"));
filterList.add(new GrayScaleFilter("Grayscale"));
filterList.add(new EdgeFilter("Edge Detection"));
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);
cropButton = new JButton("Crop");
cropButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { crop(); }
});
toolbar.add(cropButton);
RotateL = new JButton("Rotate 90 Left");
RotateL.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { Rotate90left(); }
});
toolbar.add(RotateL);
RotateR = new JButton("Rotate 90 Right");
RotateR.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { Rotate90right(); }
});
toolbar.add(RotateR);
// 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);
}
}
Komentar
Posting Komentar