/** * @author Derek Babb <[email protected]> * @version 1.0 * @since 6-28-2012 * * The PictureEdit class allows you to easily open and modify an image * at the pixel level. * * The intended purpose is to be used with Steganography and Steganalysis of images. */ import java.awt.image.BufferedImage; import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JPanel; import javax.imageio.ImageIO; import java.io.File; import java.awt.Image; import java.util.Date; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.awt.Graphics; import java.awt.Color; public class PictureEdit extends JPanel { private BufferedImage image; private BufferedImage revertImage; /** * Constructor will use the JFileChooser to open a file */ public PictureEdit() { image = null; this.open(); } /** * Constructor will use the JFileChooser to open a file * * @param fileName is the String file name including the directory path */ public PictureEdit(String fileName) { image = null; this.open(fileName); } /** * Constructor will use the JFileChooser to open a file * * @param file is the File object of the picture that will be opened. */ public PictureEdit(File file) { image = null; this.open(file); } /** * Opens a file by opening a JFileChooser which allows the user to select * the file they would like to open. * * @return true if the file successfully opened, false otherwise. */ public boolean open() { JFileChooser chooser = new JFileChooser("."); FileNameExtensionFilter filter = new FileNameExtensionFilter("PNG Images", "png"); chooser.setFileFilter(filter); int returnVal = chooser.showOpenDialog(null); if(returnVal == JFileChooser.APPROVE_OPTION) { try{ File file = chooser.getSelectedFile(); image = ImageIO.read(file); revertImage = copyImage(image); } catch(Exception e){ return false; } return true; } else { return false; } } /** * Opens an image file based on the file name in String format * * @param fileName the name of the file including file path. * @return true if the file is successfully opened, false otherwise. */ public boolean open(String fileName) { try{ File file = new File(fileName); image = ImageIO.read(file); revertImage = copyImage(image); } catch(Exception e){ return false; } return true; } /** * Opens an image file given a File object. * * @param file the File object of the image file. * @return true if the file is successfully opened, false otherwise. */ public boolean open(File file) { try{ image = ImageIO.read(file); revertImage = copyImage(image); } catch(Exception e){ return false; } return true; } /** * Reverts to the original file, all unsaved changes are lost. */ public void revert() { image = copyImage(revertImage); } /** * Saves a file by opening a JFileChooser which allows the user to select * the file they would like to save over or create a new file to save onto. * * @return true if the file successfully opened, false otherwise. */ public boolean saveAs() { JFileChooser chooser = new JFileChooser("."); int returnVal = chooser.showSaveDialog(null); if(returnVal == JFileChooser.APPROVE_OPTION) { try{ ImageIO.write(image, "png",chooser.getSelectedFile()); } catch(Exception e){ return false; } return true; } return false; } /** * Saves a file by writing a new file with the given fileName String. * CAUTION: This will overwrite any file with the name provided. No confirmation * dialog. * * @param fileName is a String with the file name and path directory. * * @return true if the file successfully opened, false otherwise. */ public boolean saveAs(String fileName) { try{ ImageIO.write(image, "png",new File(fileName)); } catch(Exception e){ return false; } return true; } /** * Returns the width of the image file * * @return integer value of the width. Will return 0 if there is no file currently open. */ public int getWidth() { if(image == null) { return 0; } else { return image.getWidth(); } } /** * Returns the height of the image file * * @return integer value of the height. Will return 0 if there is no file currently open. */ public int getHeight() { if(image == null) { return 0; } else { return image.getHeight(); } } /** * Returns the image file as an Image object. This might be used to easily display the open image. * * @return Image object of the currently open image. */ public Image getImage() { return (Image)image; } /** * Displays the current image in a new JFrame. * The title of the JFrame will be the timestamp of when it was displayed. * The timestamp allows the user to see multiple revisions and know which came first. * */ public void displayImage() { DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); Date date = new Date(); displayImage(dateFormat.format(date)); } /** * Displays the current image in a new JFrame. * The title of the window is given as a paramater. * * @param title Title of the window. * */ public void displayImage(String title) { new Window(image, title); } /** * Returns the integer value of the color at a given point. * Will return a -1 if the coordinate is outside the width/height of the open image. * * @param x x-coordinate of the selected pixel * @param y y-coordinate of the selected pixel * * @return integer value of the color at (x,y) coordinate. */ public int getRGBColor(int x, int y) { if(x < image.getWidth() && y < image.getHeight()) { return image.getRGB(x,y); } else { return -1; } } /** * Returns a Color object of the color at a given point. * Will return null if the coordinate is outside the width/height of the open image. * * @param x x-coordinate of the selected pixel * @param y y-coordinate of the selected pixel * * @return Color object of the color at (x,y) coordinate. */ public Color getColor(int x, int y) { if(x < image.getWidth() && y < image.getHeight()) { return new Color(getRGBColor(x,y)); } else { return null; } } /** * Sets the color at a given x,y coordinate. * The color is given in an integer RGB model. * * If the x,y is outside the image, the method returns false, true otherwise. * * @param x x-coordinate of the selected pixel * @param y y-coordinate of the selected pixel * @param color the color in integer RGB form * * @return Color object of the color at (x,y) coordinate. */ public boolean setColor(int x, int y, int color) { if(x < image.getWidth() && y < image.getHeight()) { image.setRGB(x, y, color); return true; } return false; } /** * Sets the color at a given x,y coordinate. * The color is given as a Color object. * * If the x,y is outside the image, the method returns false, true otherwise. * * @param x x-coordinate of the selected pixel * @param y y-coordinate of the selected pixel * @param color Color object of the color to change to * * @return Color object of the color at (x,y) coordinate. */ public boolean setColor(int x, int y, Color color) { if(x < image.getWidth() && y < image.getHeight() && color != null) { image.setRGB(x, y, color.getRGB()); return true; } return false; } private BufferedImage copyImage(BufferedImage i) { BufferedImage img = new BufferedImage(i.getWidth(), i.getHeight(), i.getType()); for (int y = 0; y < i.getHeight(); y++) { for (int x = 0; x < i.getWidth(); x++) { int rgb = i.getRGB(x, y); img.setRGB(x, y, rgb); } } return img; } private class Window extends JPanel { private BufferedImage img; public Window(BufferedImage i, String title) { img = copyImage(image); JFrame jf = new JFrame(title); jf.setSize(img.getWidth() + 16, img.getHeight() + 38); jf.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); jf.getContentPane().add(this); jf.setVisible(true); } /** * @Override to display image */ public void paintComponent(Graphics g) { super.paintComponent(g); g.drawImage(img,0,0,this); } } }