Senin, 10 Desember 2018

EAS PBO - Membuat Image Viewer


Membuat Image Viewer

(Versi update + editor)

 

Nama : Atika Rizki Nurakhmah
Nrp    : 05111740000015
Kelas : PBO - A


1. Rancangan Interfaces



2. Diagram Class



 penjelasan :
a. Class ImageViewer : Class tempat menyatukan semua class.
b. Class ImagePanel : komponen Swing yang dapat menampilkan OFImage.
c. Class ImageFileManager : clas untuk load dan save image.
d. Class OFImage : class yang mendefinisikan image ke dalam Object First format.
e. Class abstract Filter : Berisi method filter secara umum.
f. Class turunan filter : berisi method filter secara khusus berdasarkan namanya masing masing. Terdiri dari subclass :  DarkerFilter, EdgeFilter, FishEyeFilter, MirrorFilter, LighterFilter, SolarizeFilter, GrayScaleFilter, InvertFilter, ThresholdFilter, SmoothFilter, PixelizeFilter.
 
 Di dalam class ImageViewer terdapat berbagai macam Tools Image Viewer dan editor, beserta fungsinya. Tools yang ada pada image editor yang saya buat yaitu :
a. Crop : digunakan untuk memotong gambar. Pada GUI ini, crop diimplementasikan menggunakan selisih koordinat titik. User diminta menginputkan koordinat titik awal gambar akan dipotong disebelah mana, dan koordinat titik akhir pemotongan gambar.
b. Add Text: menambahkan tulisan pada gambar. Pengguna diminta memasukkan koordinat tulisan, kemudian teks yang akan ditulis serta warna teks dengan format RGB.

Selain menu Tools, juga terdapat menu View dengan fitur:
a. Zoom out : mengecilkan tampilan gambar
b. Zoom in : memperbesar tampilan gambar
c. Rotate 90 right : memutar gambar 90 derajat ke arah kanan
d. Rotate 90 left : memutar gambar 90 derajat ke arah kiri
e. Rotate 180 : memutar gambar sejauh 180 derajat

3. Implementasi program

1. Class 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;  
 /**  
  * @author Atika Rizki  
  * @version EAS/20181210  
  */  
 public class ImageViewer  
 {  
   // static fields:  
   private static final String VERSION = "Version EAS PBO ";  
   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;  
   public ImageViewer()  
   {  
     currentImage = null;  
     filters = createFilters();  
     makeFrame();  
   }  
   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);  
     showFilename(selectedFile.getPath());  
     showStatus("File loaded.");  
     frame.pack();  
   }  
   private void close()  
   {  
     currentImage = null;  
     imagePanel.clearImage();  
     showFilename(null);  
   }  
   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());  
     }  
   }  
   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 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();  
     }  
   }  
   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();  
     }  
   }  
   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 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 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"));  
     filterList.add(new FishEyeFilter("Fish Eye"));  
     return filterList;  
   }  
   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();  
     }  
   }  
   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 messages  
     filenameLabel = new JLabel();  
     contentPane.add(filenameLabel, BorderLayout.NORTH);  
     statusLabel = new JLabel(VERSION);  
     contentPane.add(statusLabel, BorderLayout.SOUTH);  
     // building is done - arrange the components     
     showFilename(null);  
     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);  
   }  
   private void makeText()  
   {  
     JTextField xField = new JTextField(5);  
     JTextField yField = new JTextField(5);  
     JTextField zField = new JTextField(5);  
     JPanel myPanel = new JPanel();  
     myPanel.add(new JLabel("R"));  
     myPanel.add(xField);  
     myPanel.add(Box.createVerticalStrut(15)); // a spacer  
     myPanel.add(new JLabel("G"));  
     myPanel.add(yField);  
     myPanel.add(Box.createVerticalStrut(15)); // a spacer  
     myPanel.add(new JLabel("B"));  
     myPanel.add(zField);  
     if(currentImage != null) {  
       int width = currentImage.getWidth();  
       int height = currentImage.getHeight();  
       int xPosition = Integer.parseInt(JOptionPane.showInputDialog("Pixel Position X"));  
       int yPosition = Integer.parseInt(JOptionPane.showInputDialog("Pixel Position Y"));  
       float fontSize = Float.parseFloat(JOptionPane.showInputDialog("Font Size"));  
       String addText = JOptionPane.showInputDialog("Write Something..");  
       int result = JOptionPane.showConfirmDialog(null, myPanel, "Font Color", JOptionPane.OK_CANCEL_OPTION);  
       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++) {  
           Color col = currentImage.getPixel(x, y);  
           newImage.setPixel(x, y, col);  
         }  
       }  
       int r = Integer.parseInt(xField.getText());  
       int gr = Integer.parseInt(yField.getText());  
       int b = Integer.parseInt(zField.getText());  
       Color c = new Color(r,gr,b);  
       Graphics g = newImage.getGraphics();  
       g.setFont(g.getFont().deriveFont(fontSize));  
       g.setColor(c);  
       g.drawString(addText, xPosition, yPosition);  
       g.dispose();  
       currentImage = newImage;  
       imagePanel.setImage(currentImage);  
     }  
   }  
   private void RotateR90() {  
     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 RotateL90() {  
     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 Rotate180() {  
     if(currentImage != null) {  
       // create new image with double size  
       int width = currentImage.getWidth();  
       int height = currentImage.getHeight();  
       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++) {  
           Color col = currentImage.getPixel(width-x-1, height-y-1);  
           newImage.setPixel(x, y, 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("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);  
      }  
     menu = new JMenu ("Tools");  
     menubar.add(menu);  
     item = new JMenuItem ("Crop image");  
     item.addActionListener(new ActionListener() {  
       public void actionPerformed(ActionEvent e) {   
         crop ();}  
       });  
       menu.add(item);   
       item = new JMenuItem ("Add Text to image");  
       item.addActionListener(new ActionListener() {  
       public void actionPerformed(ActionEvent e) {   
         makeText ();}  
       });  
       menu.add(item);  
     menu = new JMenu("View");  
     menubar.add(menu);  
     item=new JMenuItem("Zoom Out (-)");  
       item.addActionListener(new ActionListener() {  
       public void actionPerformed(ActionEvent e) {   
         makeSmaller ();}  
       });  
       menu.add(item);  
     item=new JMenuItem("Zoom In (+)");  
       item.addActionListener(new ActionListener() {  
       public void actionPerformed(ActionEvent e) {   
         makeLarger ();}  
       });  
       menu.add(item);  
     item=new JMenuItem("Rotate 90 right");  
       item.addActionListener(new ActionListener() {  
       public void actionPerformed(ActionEvent e) {   
         RotateR90();}  
       });  
       menu.add(item);  
     item=new JMenuItem("Rotate 90 left");  
       item.addActionListener(new ActionListener() {  
       public void actionPerformed(ActionEvent e) {   
         RotateL90();}  
       });  
       menu.add(item);  
     item=new JMenuItem("Rotate 180");  
       item.addActionListener(new ActionListener() {  
       public void actionPerformed(ActionEvent e) {   
         Rotate180();}  
       });  
       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);  
   }  
 }  

2. Class ImageFileManager


import java.awt.image.*;  
 import javax.imageio.*;  
 import java.io.*;  
 /**  
  * @author Atika Rizki  
  * @version EAS/20181210  
  */  
 public class ImageFileManager  
 {  
   private static final String IMAGE_FORMAT = "jpg";  
   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;  
     }  
   }  
 }  

3. Class ImagePanel

 import java.awt.*;  
 import javax.swing.*;  
 import java.awt.image.*;  
 /**  
  * @author Atika Rizki  
  * @version EAS/20181210  
  */  
 public class ImagePanel extends JComponent  
 {  
   private int width, height;  
   private OFImage panelImage;  
   public ImagePanel()  
   {  
     width = 360;    
     height = 240;  
     panelImage = null;  
   }  
   public void setImage(OFImage image)  
   {  
     if(image != null) {  
       width = image.getWidth();  
       height = image.getHeight();  
       panelImage = image;  
       repaint();  
     }  
   }  
   public void clearImage()  
   {  
     Graphics imageGraphics = panelImage.getGraphics();  
     imageGraphics.setColor(Color.LIGHT_GRAY);  
     imageGraphics.fillRect(0, 0, width, height);  
     repaint();  
   }  
   public Dimension getPreferredSize()  
   {  
     return new Dimension(width, height);  
   }  
   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);  
     }  
   }  
 }  

4. Class OFImage

import java.awt.*;  
 import java.awt.image.*;  
 import javax.swing.*;  
 /**  
  * @author Atika Rizki  
  * @version EAS/20181210  
  */  
 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);  
   }  
 }  

5. Class Filter 

/**  
  * @author Atika Rizki  
  * @version EAS/20181210  
  */  
 public abstract class Filter  
 {  
   private String name;  
   public Filter(String name)  
   {  
     this.name = name;  
   }  
   public String getName()  
   {  
     return name;  
   }  
   public abstract void apply(OFImage image);  
 }  

6.sub Class DarkerFilter

 /**   
  * @author Atika Rizki  
  * @version EAS/20181210  
  */  
 public class DarkerFilter extends Filter  
 {  
   public DarkerFilter(String name)  
   {  
     super(name);  
   }  
   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());  
       }  
     }  
   }  
 }  

7. sub Class InvertFilter

import java.awt.Color;  
 /**  
  * @author Atika Rizki   
  * @version EAS/20181210  
  */  
 public class InvertFilter extends Filter  
 {  
   public InvertFilter(String name)  
   {  
     super(name);  
   }  
   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()));  
       }  
     }  
   }  
 }  

8. sub Class MirrorFilter

 import java.awt.Color;  
 /**  
  * @author Atika Rizki  
  * @version EAS/20181210  
  */  
 public class MirrorFilter extends Filter  
 {  
      public MirrorFilter(String name)  
   {  
     super(name);  
      }  
   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);  
       }  
     }  
   }  
 }  

9. sub Class FishEyeFilter

import java.awt.Color;  
 /**  
  * @author Atika Rizki  
  * @version EAS/20181210  
  */  
 public class FishEyeFilter extends Filter  
 {  
   private final static int SCALE = 20;   
   private final static double TWO_PI = 2 * Math.PI;  
   public FishEyeFilter(String name)  
   {  
     super(name);  
   }  
   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]));  
       }  
     }  
   }  
   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) * TWO_PI) * SCALE);  
     }  
     return xArray;  
   }  
   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) * TWO_PI) * SCALE);  
     }  
     return yArray;  
   }  
 }  

10. sub Class LighterFilter

/**  
  * @author Atika Rizki  
  * @version EAS/20181210  
  */  
 public class LighterFilter extends Filter  
 {  
      public LighterFilter(String name)  
   {  
     super(name);  
      }  
   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());  
       }  
     }  
   }  
 }  

11. sub Class SolarizeFilter

import java.awt.Color;  
 /**  
  * @author Atika Rizki  
  * @version EAS/20181210  
  */  
 public class SolarizeFilter extends Filter  
 {  
   public SolarizeFilter(String name)  
   {  
     super(name);  
   }  
   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));  
       }  
     }  
   }  
 }  

12. sub Class GrayScaleFilter

 import java.awt.Color;  
 /**  
  * @author Atika Rizki  
  * @version EAS/20181210  
  */  
 public class GrayScaleFilter extends Filter  
 {  
      public GrayScaleFilter(String name)  
   {  
     super(name);  
      }  
   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));  
       }  
     }  
   }  
 }  

13. sub Class ThresholdFilter

import java.awt.Color;  
 /**  
  * @author Atika Rizki  
  * @version EAS/20181210  
  */  
 public class ThresholdFilter extends Filter  
 {  
      public ThresholdFilter(String name)  
   {  
     super(name);  
      }  
   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);  
         }  
       }  
     }  
   }  
 }  

14. sub Class SmoothFilter

 import java.awt.Color;  
 import java.util.List;  
 import java.util.ArrayList;  
 /**  
  * @author Atika Rizki  
  * @version EAS/20181210  
  */  
 public class SmoothFilter extends Filter  
 {  
   private OFImage original;  
   private int width;  
   private int height;  
   public SmoothFilter(String name)  
   {  
     super(name);  
   }  
   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));  
       }  
     }  
   }  
   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));  
   }  
   private int avgRed(List<Color> pixels)  
   {  
     int total = 0;  
     for(Color color : pixels) {  
       total += color.getRed();  
     }  
     return total / pixels.size();  
   }  
   private int avgGreen(List<Color> pixels)  
   {  
     int total = 0;  
     for(Color color : pixels) {  
       total += color.getGreen();  
     }  
     return total / pixels.size();  
   }  
   private int avgBlue(List<Color> pixels)  
   {  
     int total = 0;  
     for(Color color : pixels) {  
       total += color.getBlue();  
     }  
     return total / pixels.size();  
   }  
 }  

15. sub Class PixelizeFilter

 import java.awt.Color;  
 /**  
  * @author Atika Rizki  
  * @version EAS/20181210  
  */  
 public class PixelizeFilter extends Filter  
 {  
   public PixelizeFilter(String name)  
   {  
     super(name);  
   }  
   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);  
           }  
         }  
       }  
     }  
   }  
 }  

16. sub Class EdgeFilter

import java.awt.Color;  
 import java.util.List;  
 import java.util.ArrayList;  
 /**  
  * @author Atika Rizki  
  * @version EAS/20181210  
  */  
 public class EdgeFilter extends Filter  
 {  
   private static final int TOLERANCE = 20;  
   private OFImage original;  
   private int width;  
   private int height;  
   public EdgeFilter(String name)  
   {  
     super(name);  
   }  
   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));  
       }  
     }  
   }  
   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));  
   }  
   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;  
   }  
   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;  
   }  
   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;  
   }  
 }  


HASIL
Display Image Viewer+Editor

Open file

Tampilan normal

Filter yang tersedia

Tools yang tersedia

Tools pada menu View

About Image Viewer
crop tools

crop tools

zoom out view

zoom in view

rotate 90 right

rotate 90 left

rotate 180 derajat

add text to image

add text to image

SEKIAN DAN TERIMA KASIH :)

Minggu, 02 Desember 2018

Game Pong with BlueJ

 

Membuat Game Pong

 


Nama : Atika Rizki Nurakhmah
NRP : 05111740000015
Kelas : PBO - A

Tugas saya kali ini adalah membuat game pong.
Pong adalah permainan video generasi pertama yang dirilis sebagai permainan arkade yang dioperasikan dengan koin yang dikembangkan oleh Atari Inc. pada tanggal 29 November 1972. Pong didasari dari permainan atau olahraga tenis meja (Ping pong), nama permainan ini berasal dari suara yang dihasilkan ketika memukul bola ping pong.Kata Pong telah didaftarkan sebagai merek dari Atari Interactive. 
Pong adalah permainan video olah raga dua dimensi yang mensimulasikan sebuah permainan tenis meja. Sang pemain mengerakan sebuah bat yang bergerak naik-turun, permainan ini dapat dimainkan dengan komputer atau dua orang yang mengerakan bat di sebelah kiri. Pemain memukul bola bolak-balik. Untuk memenangkan permainan, sang pemain harus memukul bola tersebut sampai sang lawan tidak bisa memukul bola tersebut.
(sumber : https://id.wikipedia.org/wiki/Pong ) 

Tugas kali ini menggunakan package pada Blue J. Package adalah sarana/cara pengelompokkan dan pengorganisasian kelas-kelas dan interface yang sekelompok menjadi suatu unit tunggal dalam library. Package juga mempengaruhi mekanisme hak akses ke kelas-kelas di dalamnya.
(sumber : https://halimi1010.wordpress.com/category/j2se/pbo-1/package-dalam-java/)

Berikut diagram class project ini.
Package pong

diagram class game pong

Berikut Source code nya:
1. Class Paddle

package pong;  
 import java.awt.Color;  
 import java.awt.Graphics;  
 public class Paddle  
 {  
   public int paddleNumber;  
   public int x, y, width = 50, height = 250;  
   public int score;  
   public Paddle(Pong pong, int paddleNumber)  
   {  
     this.paddleNumber = paddleNumber;  
     if (paddleNumber == 1)  
     {  
       this.x = 0;  
     }  
     if (paddleNumber == 2)  
     {  
       this.x = pong.width - width;  
     }  
     this.y = pong.height / 2 - this.height / 2;  
   }  
   public void render(Graphics g)  
   {  
     g.setColor(Color.WHITE);  
     g.fillRect(x, y, width, height);  
   }  
   public void move(boolean up)  
   {  
     int speed = 15;  
     if (up)  
     {  
       if (y - speed > 0)  
       {  
         y -= speed;  
       }  
       else  
       {  
         y = 0;  
       }  
     }  
     else  
     {  
       if (y + height + speed < Pong.pong.height)  
       {  
         y += speed;  
       }  
       else  
       {  
         y = Pong.pong.height - height;  
       }  
     }  
   }  
 }  

2. Class Ball

package pong;  
 import java.awt.Color;  
 import java.awt.Graphics;  
 import java.util.Random;  
 public class Ball  
 {  
   public int x, y, width = 25, height = 25;  
   public int motionX, motionY;  
   public Random random;  
   private Pong pong;  
   public int amountOfHits;  
   public Ball(Pong pong)  
   {  
     this.pong = pong;  
     this.random = new Random();  
     spawn();  
   }  
   public void update(Paddle paddle1, Paddle paddle2)  
   {  
     int speed = 5;  
     this.x += motionX * speed;  
     this.y += motionY * speed;  
     if (this.y + height - motionY > pong.height || this.y + motionY < 0)  
     {  
       if (this.motionY < 0)  
       {  
         this.y = 0;  
         this.motionY = random.nextInt(4);  
         if (motionY == 0)  
         {  
           motionY = 1;  
         }  
       }  
       else  
       {  
         this.motionY = -random.nextInt(4);  
         this.y = pong.height - height;  
         if (motionY == 0)  
         {  
           motionY = -1;  
         }  
       }  
     }  
     if (checkCollision(paddle1) == 1)  
     {  
       this.motionX = 1 + (amountOfHits / 5);  
       this.motionY = -2 + random.nextInt(4);  
       if (motionY == 0)  
       {  
         motionY = 1;  
       }  
       amountOfHits++;  
     }  
     else if (checkCollision(paddle2) == 1)  
     {  
       this.motionX = -1 - (amountOfHits / 5);  
       this.motionY = -2 + random.nextInt(4);  
       if (motionY == 0)  
       {  
         motionY = 1;  
       }  
       amountOfHits++;  
     }  
     if (checkCollision(paddle1) == 2)  
     {  
       paddle2.score++;  
       spawn();  
     }  
     else if (checkCollision(paddle2) == 2)  
     {  
       paddle1.score++;  
       spawn();  
     }  
   }  
   public void spawn()  
   {  
     this.amountOfHits = 0;  
     this.x = pong.width / 2 - this.width / 2;  
     this.y = pong.height / 2 - this.height / 2;  
     this.motionY = -2 + random.nextInt(4);  
     if (motionY == 0)  
     {  
       motionY = 1;  
     }  
     if (random.nextBoolean())  
     {  
       motionX = 1;  
     }  
     else  
     {  
       motionX = -1;  
     }  
   }  
   public int checkCollision(Paddle paddle)  
   {  
     if (this.x < paddle.x + paddle.width && this.x + width > paddle.x && this.y < paddle.y + paddle.height && this.y + height > paddle.y)  
     {  
       return 1; //bounce  
     }  
     else if ((paddle.x > x && paddle.paddleNumber == 1) || (paddle.x < x - width && paddle.paddleNumber == 2))  
     {  
       return 2; //score  
     }  
     return 0; //nothing  
   }  
   public void render(Graphics g)  
   {  
     g.setColor(Color.WHITE);  
     g.fillOval(x, y, width, height);  
   }  
 } 

3. Class Renderer

package pong;  
 import java.awt.Graphics;  
 import java.awt.Graphics2D;  
 import javax.swing.JPanel;  
 public class Renderer extends JPanel  
 {  
   private static final long serialVersionUID = 1L;  
   @Override  
   protected void paintComponent(Graphics g)  
   {  
     super.paintComponent(g);  
     Pong.pong.render((Graphics2D) g);  
   }  
 }  

4. Class Pong
package pong;  
 import java.awt.BasicStroke;  
 import java.awt.Color;  
 import java.awt.Font;  
 import java.awt.Graphics2D;  
 import java.awt.RenderingHints;  
 import java.awt.event.ActionEvent;  
 import java.awt.event.ActionListener;  
 import java.awt.event.KeyEvent;  
 import java.awt.event.KeyListener;  
 import java.util.Random;   
 import javax.swing.JFrame;  
 import javax.swing.Timer;  
 public class Pong implements ActionListener, KeyListener  
 {  
   public static Pong pong;   
   public int width = 700, height = 700;  
   public Renderer renderer;   
   public Paddle player1;  
   public Paddle player2;  
   public Ball ball;   
   public boolean bot = false, selectingDifficulty;  
   public boolean w, s, up, down;  
   public int gameStatus = 0, scoreLimit = 7, playerWon; //0 = Menu, 1 = Paused, 2 = Playing, 3 = Over  
   public int botDifficulty, botMoves, botCooldown = 0;   
   public Random random;  
   public JFrame jframe;  
   public Pong()  
   {  
     Timer timer = new Timer(20, this);  
     random = new Random();  
     jframe = new JFrame("Pong");  
     renderer = new Renderer();  
     jframe.setSize(width + 15, height + 35);  
     jframe.setVisible(true);  
     jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
     jframe.add(renderer);  
     jframe.addKeyListener(this);  
     timer.start();  
   }  
   public void start()  
   {  
     gameStatus = 2;  
     player1 = new Paddle(this, 1);  
     player2 = new Paddle(this, 2);  
     ball = new Ball(this);  
   }  
   public void update()  
   {  
     if (player1.score >= scoreLimit)  
     {  
       playerWon = 1;  
       gameStatus = 3;  
     }  
     if (player2.score >= scoreLimit)  
     {  
       gameStatus = 3;  
       playerWon = 2;  
     }  
     if (w)  
     {  
       player1.move(true);  
     }  
     if (s)  
     {  
       player1.move(false);  
     }  
     if (!bot)  
     {  
       if (up)  
       {  
         player2.move(true);  
       }  
       if (down)  
       {  
         player2.move(false);  
       }  
     }  
     else  
     {  
       if (botCooldown > 0)  
       {  
         botCooldown--;  
         if (botCooldown == 0)  
         {  
           botMoves = 0;  
         }  
       }  
       if (botMoves < 10)  
       {  
         if (player2.y + player2.height / 2 < ball.y)  
         {  
           player2.move(false);  
           botMoves++;  
         }  
         if (player2.y + player2.height / 2 > ball.y)  
         {  
           player2.move(true);  
           botMoves++;  
         }  
         if (botDifficulty == 0)  
         {  
           botCooldown = 20;  
         }  
         if (botDifficulty == 1)  
         {  
           botCooldown = 15;  
         }  
         if (botDifficulty == 2)  
         {  
           botCooldown = 10;  
         }  
       }  
     }  
     ball.update(player1, player2);  
   }  
   public void render(Graphics2D g)  
   {  
     g.setColor(Color.BLACK);  
     g.fillRect(0, 0, width, height);  
     g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);  
     if (gameStatus == 0)  
     {  
       g.setColor(Color.WHITE);  
       g.setFont(new Font("Arial", 1, 50));  
       g.drawString("PONG", width / 2 - 75, 50);  
       if (!selectingDifficulty)  
       {  
         g.setFont(new Font("Arial", 1, 30));  
         g.drawString("Press Space to Play", width / 2 - 150, height / 2 - 25);  
         g.drawString("Press Shift to Play with Bot", width / 2 - 200, height / 2 + 25);  
         g.drawString("<< Score Limit: " + scoreLimit + " >>", width / 2 - 150, height / 2 + 75);  
       }  
     }  
     if (selectingDifficulty)  
     {  
       String string = botDifficulty == 0 ? "Easy" : (botDifficulty == 1 ? "Medium" : "Hard");  
       g.setFont(new Font("Arial", 1, 30));  
       g.drawString("<< Bot Difficulty: " + string + " >>", width / 2 - 180, height / 2 - 25);  
       g.drawString("Press Space to Play", width / 2 - 150, height / 2 + 25);  
     }  
     if (gameStatus == 1)  
     {  
       g.setColor(Color.WHITE);  
       g.setFont(new Font("Arial", 1, 50));  
       g.drawString("PAUSED", width / 2 - 103, height / 2 - 25);  
     }  
     if (gameStatus == 1 || gameStatus == 2)  
     {  
       g.setColor(Color.WHITE);  
       g.setStroke(new BasicStroke(5f));  
       g.drawLine(width / 2, 0, width / 2, height);  
       g.setStroke(new BasicStroke(2f));  
       g.drawOval(width / 2 - 150, height / 2 - 150, 300, 300);  
       g.setFont(new Font("Arial", 1, 50));  
       g.drawString(String.valueOf(player1.score), width / 2 - 90, 50);  
       g.drawString(String.valueOf(player2.score), width / 2 + 65, 50);  
       player1.render(g);  
       player2.render(g);  
       ball.render(g);  
     }  
     if (gameStatus == 3)  
     {  
       g.setColor(Color.WHITE);  
       g.setFont(new Font("Arial", 1, 50));  
       g.drawString("PONG", width / 2 - 75, 50);  
       if (bot && playerWon == 2)  
       {  
         g.drawString("The Bot Wins!", width / 2 - 170, 200);  
       }  
       else  
       {  
         g.drawString("Player " + playerWon + " Wins!", width / 2 - 165, 200);  
       }  
       g.setFont(new Font("Arial", 1, 30));  
       g.drawString("Press Space to Play Again", width / 2 - 185, height / 2 - 25);  
       g.drawString("Press ESC for Menu", width / 2 - 140, height / 2 + 25);  
     }  
   }  
   @Override  
   public void actionPerformed(ActionEvent e)  
   {  
     if (gameStatus == 2)  
     {  
       update();  
     }  
     renderer.repaint();  
   }  
   public static void main(String[] args)  
   {  
     pong = new Pong();  
   }  
   @Override  
   public void keyPressed(KeyEvent e)  
   {  
     int id = e.getKeyCode();  
     if (id == KeyEvent.VK_W)  
     {  
       w = true;  
     }  
     else if (id == KeyEvent.VK_S)  
     {  
       s = true;  
     }  
     else if (id == KeyEvent.VK_UP)  
     {  
       up = true;  
     }  
     else if (id == KeyEvent.VK_DOWN)  
     {  
       down = true;  
     }  
     else if (id == KeyEvent.VK_RIGHT)  
     {  
       if (selectingDifficulty)  
       {  
         if (botDifficulty < 2)  
         {  
           botDifficulty++;  
         }  
         else  
         {  
           botDifficulty = 0;  
         }  
       }  
       else if (gameStatus == 0)  
       {  
         scoreLimit++;  
       }  
     }  
     else if (id == KeyEvent.VK_LEFT)  
     {  
       if (selectingDifficulty)  
       {  
         if (botDifficulty > 0)  
         {  
           botDifficulty--;  
         }  
         else  
         {  
           botDifficulty = 2;  
         }  
       }  
       else if (gameStatus == 0 && scoreLimit > 1)  
       {  
         scoreLimit--;  
       }  
     }  
     else if (id == KeyEvent.VK_ESCAPE && (gameStatus == 2 || gameStatus == 3))  
     {  
       gameStatus = 0;  
     }  
     else if (id == KeyEvent.VK_SHIFT && gameStatus == 0)  
     {  
       bot = true;  
       selectingDifficulty = true;  
     }  
     else if (id == KeyEvent.VK_SPACE)  
     {  
       if (gameStatus == 0 || gameStatus == 3)  
       {  
         if (!selectingDifficulty)  
         {  
           bot = false;  
         }  
         else  
         {  
           selectingDifficulty = false;  
         }  
         start();  
       }  
       else if (gameStatus == 1)  
       {  
         gameStatus = 2;  
       }  
       else if (gameStatus == 2)  
       {  
         gameStatus = 1;  
       }  
     }  
   }  
   @Override  
   public void keyReleased(KeyEvent e)  
   {  
     int id = e.getKeyCode();  
     if (id == KeyEvent.VK_W)  
     {  
       w = false;  
     }  
     else if (id == KeyEvent.VK_S)  
     {  
       s = false;  
     }  
     else if (id == KeyEvent.VK_UP)  
     {  
       up = false;  
     }  
     else if (id == KeyEvent.VK_DOWN)  
     {  
       down = false;  
     }  
   }  
   @Override  
   public void keyTyped(KeyEvent e)  
   {  
   }  
 } 


Cara menjalankan Game Pong

klik kanan pada class pong, lalu pilih void main (String [] Args)


klik OK

Tampilan Game Pong




Sekian dan terima kasih :)

EAS PBO - Membuat Image Viewer

Membuat Image Viewer (Versi update + editor)   Nama : Atika Rizki Nurakhmah Nrp    : 05111740000015 Kelas : PBO - A ...