MEMBUAT IMAGE EDITOR
1. Gambarkan rancangan interfacenya.
2. Gambarkan dan jelaskan Class Diaram penyusun dari image viewer yang akan dibuat.
- Image viewer : Class utama dari image editor.
- Image panel : mengatur letak letak panel yang akan dibentuk dari OFImage
- OFImage : Class yang mendefinisikan gambar kedalam format OF (Object First)
- File Manager : mengatur pengelolaan file seperti membuka file dan menyimpan file.
- Filter : untuk menambah efek-efek yang disediakan terhadap gambar. Terdiri atas 3 filter yaitu Grayscale (hitam-putih), Mirror (Pencerminan), dan Darker (Menggelapkan).
3. Implementasikan ke dalam program.
- Class ImageFileManager
import java.awt.image.*;
import javax.imageio.*;
import java.io.*;
/**
* Membuat Image Editor
*
*
* @author (Christine Amelia)
* @version (UAS PBO B)
*/
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;
}
}
public static void saveImage(OFImage image, File file)
{
try
{
ImageIO.write(image, IMAGE_FORMAT, file);
}
catch(IOException exc)
{
return;
}
}
}
- Class ImagePanel
import java.awt.image.*;
import java.awt.*;
import javax.swing.*;
/**
* Membuat Image Editor
*
* @author (Christine Amelia)
* @version (UAS PBO B)
*/
public class ImagePanel extends JComponent
{
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 = 350; // arbitrary size for empty panel
height = 250;
panelImage = null;
}
// Set the image that this panel should show.
public void setImage(OFImage image)
{
if(image != null)
{
width = image.getWidth();
height = image.getHeight();
panelImage = image;
repaint();
}
}
// Clear the image on this panel.
public void clearImage()
{
Graphics imageGraphics = panelImage.getGraphics();
imageGraphics.setColor(Color.LIGHT_GRAY);
imageGraphics.fillRect(0, 0, width, height);
repaint();
}
// The following methods are redefinitions of methods
// inherited from superclasses.
/**
* Tell the layout manager how big we would like to be.
* (This method gets called by layout managers for placing
* the components.)
*
* @return The preferred dimension for this component.
*/
public Dimension getPreferredSize()
{
return new Dimension(width, height);
}
/**
* This component needs to be redisplayed. Copy the internal image
* to screen. (This method gets called by the Swing screen painter
* every time it want this component displayed.)
*
* @param g The graphics context that can be used to draw on this component.
*/
public void paintComponent(Graphics g)
{
Dimension size = getSize();
g.clearRect(0, 0, size.width, size.height);
if(panelImage != null)
{
g.drawImage(panelImage, 0, 0, null);
}
}
}
- Class OFImage
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
/**
* Membuat Image Editor
*
* @author (Christine Amelia)
* @version (UAS PBO B)
*/
public class OFImage extends BufferedImage
{
public OFImage(BufferedImage image)
{
super(image.getColorModel(), image.copyData(null), image.isAlphaPremultiplied(), null);
}
public OFImage(int width, int height)
{
super(width, height, TYPE_INT_RGB);
}
public void setPixel(int x, int y, Color col)
{
int pixel = col.getRGB();
setRGB(x, y, pixel);
}
public Color getPixel(int x, int y)
{
int pixel = getRGB(x, y);
return new Color(pixel);
}
// Make this image a bit darker.
public void darker()
{
int height = getHeight();
int width = getWidth();
for(int y = 0; y < height; y++)
{
for(int x = 0; x < width; x++)
{
setPixel(x, y, getPixel(x, y).darker());
}
}
}
// Make this image a bit lighter.
public void lighter()
{
int height = getHeight();
int width = getWidth();
for(int y = 0; y < height; y++)
{
for(int x = 0; x < width; x++)
{
setPixel(x, y, getPixel(x, y).brighter());
}
}
}
/**
* Perform a three level threshold operation.
* That is: repaint the image with only three color values:
* white, gray, and black.
*/
public void threshold()
{
int height = getHeight();
int width = getWidth();
for(int y = 0; y < height; y++)
{
for(int x = 0; x < width; x++)
{
Color pixel = getPixel(x, y);
int brightness = (pixel.getRed() + pixel.getBlue() + pixel.getGreen()) / 3;
if(brightness <= 85)
{
setPixel(x, y, Color.BLACK);
}
else if(brightness <= 170)
{
setPixel(x, y, Color.GRAY);
}
else
{
setPixel(x, y, Color.WHITE);
}
}
}
}
}
- Class Filter
/**
* Membuat Image Editor
*
* @author (Christine Amelia)
* @version (UAS PBO B)
*/
public abstract class Filter
{
private String name;
public Filter(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
// Apply this filter to an image.
public abstract void apply(OFImage image);
}
- Class DarkerFilter
/**
* Membuat Image Editor
*
* @author (Christine Amelia)
* @version (UAS PBO B)
*/
public class DarkerFilter extends Filter
{
public DarkerFilter(String name)
{
super(name);
}
// Apply this filter to an image.
public void apply(OFImage image)
{
int height = image.getHeight();
int width = image.getWidth();
for(int y = 0; y < height; y++)
{
for(int x = 0; x < width; x++)
{
image.setPixel(x, y, image.getPixel(x, y).darker());
}
}
}
}
- Class MirrorFilter
import java.awt.Color;
/**
* Membuat Image Editor
*
* @author (Christine Amelia)
* @version (UAS PBO B)
*/
public class MirrorFilter extends Filter
{
public MirrorFilter(String name)
{
super(name);
}
// Apply this filter to an image.
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);
}
}
}
}
- Class GrayScaleFilter
import java.awt.Color;
/**
* Membuat Image Editor
*
* @author (Christine Amelia)
* @version (UAS PBO B)
*/
public class GrayScaleFilter extends Filter
{
public GrayScaleFilter(String name)
{
super(name);
}
// Apply this filter to an image.
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));
}
}
}
}
- Class ImageViewer
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
import java.io.File;
/**
* Membuat Image Editor
* Main class
*
* @author (Christine Amelia)
* @version (UAS PBO B)
*/
public class ImageViewer
{
private static final String VERSION = "Version 3.1";
private static JFileChooser fileChooser = new JFileChooser(System.getProperty("user.dir"));
private JFrame frame;
private ImagePanel imagePanel;
private JButton textButton;
private JButton zoominButton;
private JButton zoomoutButton;
private JButton cropButton;
private JButton rotate1Button;
private JButton rotate2Button;
private JLabel filenameLabel;
private JLabel statusLabel;
private OFImage currentImage;
private List<Filter> filters;
public ImageViewer()
{
currentImage = null;
filters = createFilters();
makeFrame();
}
private void makeText()
{
if(currentImage !=null)
{
int width = currentImage.getWidth();
int height = currentImage.getHeight();
String addText = JOptionPane.showInputDialog("Type something");
float fontSize = Float.parseFloat(JOptionPane.showInputDialog("Font Size"));
int xPosition = Integer.parseInt(JOptionPane.showInputDialog("X Position"));
int yPosition = Integer.parseInt(JOptionPane.showInputDialog("Y Position"));
OFImage newImage = new OFImage(width,height);
for(int y = 0; y < height; y++)
{
for(int x = 0; x < width; x++)
{
Color col = currentImage.getPixel(x, y);
newImage.setPixel(x, y, col);
}
}
Graphics g = newImage.getGraphics();
g.setFont(g.getFont().deriveFont(fontSize));
g.drawString(addText, xPosition, yPosition);
g.dispose();
currentImage = newImage;
imagePanel.setImage(currentImage);
}
}
private void openFile()
{
int returnVal = fileChooser.showOpenDialog(frame);
if(returnVal != JFileChooser.APPROVE_OPTION)
{
return;
}
File selectedFile = fileChooser.getSelectedFile();
currentImage = ImageFileManager.loadImage(selectedFile);
if(currentImage == null)
{
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();
}
private void close()
{
currentImage = null;
imagePanel.clearImage();
showFilename(null);
setButtonsEnabled(false);
}
private void saveAs()
{
if(currentImage != null)
{
int returnVal = fileChooser.showSaveDialog(frame);
if(returnVal != JFileChooser.APPROVE_OPTION)
{
return;
}
File selectedFile = fileChooser.getSelectedFile();
ImageFileManager.saveImage(currentImage, selectedFile);
showFilename(selectedFile.getPath());
}
}
private void quit()
{
System.exit(0);
}
private void applyFilter(Filter filter)
{
if(currentImage != null)
{
filter.apply(currentImage);
frame.repaint();
showStatus("Applied: " + filter.getName());
}
else
{
showStatus("No image loaded.");
}
}
private void showAbout()
{
JOptionPane.showMessageDialog(frame,"ImageViewer\n" + VERSION,"About ImageViewer", JOptionPane.INFORMATION_MESSAGE);
}
private void makeZoomIn()
{
if(currentImage != null)
{
int width = currentImage.getWidth();
int height = currentImage.getHeight();
OFImage newImage = new OFImage(width * 2, height * 2);
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();
}
}
private void makeZoomOut()
{
if(currentImage != null)
{
int width = currentImage.getWidth() / 2;
int height = currentImage.getHeight() / 2;
OFImage newImage = new OFImage(width, height);
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();
}
}
private void crop()
{
if (currentImage != null)
{
int width = currentImage.getWidth();
int height = currentImage.getWidth();
int xAwal = Integer.parseInt(JOptionPane.showInputDialog("x.akhir"));
int yAwal = Integer.parseInt(JOptionPane.showInputDialog("y.akhir"));
int xAkhir = Integer.parseInt(JOptionPane.showInputDialog("x.awal"));
int yAkhir = Integer.parseInt(JOptionPane.showInputDialog("y.awal"));
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();
}
}
private void showFilename(String filename)
{
if(filename == null)
{
filenameLabel.setText("No file displayed.");
}
else
{
filenameLabel.setText("File: " + filename);
}
}
private void showStatus(String text)
{
statusLabel.setText(text);
}
private void setButtonsEnabled(boolean status)
{
zoominButton.setEnabled(status);
zoomoutButton.setEnabled(status);
cropButton.setEnabled(status);
rotate1Button.setEnabled(status);
rotate2Button.setEnabled(status);
}
private List<Filter> createFilters()
{
List<Filter> filterList = new ArrayList<Filter>();
filterList.add(new DarkerFilter("Darker"));
filterList.add(new MirrorFilter("Mirror"));
filterList.add(new GrayScaleFilter("Grayscale"));
return filterList;
}
private void makeFrame()
{
frame = new JFrame("ImageViewer");
JPanel contentPane = (JPanel)frame.getContentPane();
contentPane.setBorder(new EmptyBorder(6, 6, 6, 6));
makeMenuBar(frame);
contentPane.setLayout(new BorderLayout(6, 6));
imagePanel = new ImagePanel();
imagePanel.setBorder(new EtchedBorder());
contentPane.add(imagePanel, BorderLayout.CENTER);
filenameLabel = new JLabel();
contentPane.add(filenameLabel, BorderLayout.NORTH);
statusLabel = new JLabel(VERSION);
contentPane.add(statusLabel, BorderLayout.SOUTH);
JPanel toolbar = new JPanel();
toolbar.setLayout(new GridLayout(0, 1));
textButton = new JButton("Add Text");
textButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
makeText();
}
});
toolbar.add(textButton);
zoominButton = new JButton("Zoom In");
zoominButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
makeZoomIn();
}
});
toolbar.add(zoominButton);
zoomoutButton = new JButton("Zoom Out");
zoomoutButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
makeZoomOut();
}
});
toolbar.add(zoomoutButton);
cropButton = new JButton("Crop");
cropButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
crop();
}
});
toolbar.add(cropButton);
rotate1Button = new JButton("Rotate 90 Left");
rotate1Button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
Rotate90left();
}
});
toolbar.add(rotate1Button);
rotate2Button = new JButton("Rotate 90 Right");
rotate2Button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
Rotate90right();
}
});
toolbar.add(rotate2Button);
JPanel flow = new JPanel();
flow.add(toolbar);
contentPane.add(flow, BorderLayout.WEST);
showFilename(null);
setButtonsEnabled(false);
frame.pack();
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation(d.width/2 - frame.getWidth()/2, d.height/2 - frame.getHeight()/2);
frame.setVisible(true);
}
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();
}
}
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();
}
}
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("Effect");
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);
}
}
Hasil:
- Tampilan awal dan saat memunculkan gambar
Tidak ada komentar:
Posting Komentar