import java.awt.Color; import java.io.File; import java.net.URL; import java.awt.geom.AffineTransform; import java.awt.image.AffineTransformOp; import java.awt.image.BufferedImage; import java.awt.image.BufferedImageOp; import java.awt.image.ColorModel; import java.awt.image.Raster; import java.awt.image.WritableRaster; import javax.imageio.ImageIO; import javax.swing.ImageIcon; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; /** * This class allows you to view and edit pictures. */ public class Picture { private String source; private JFrame frame; private JLabel label; private BufferedImage image; /** Constructs a blank picture. */ public Picture() { frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); label = new JLabel("(No image)"); frame.add(label); frame.pack(); frame.setVisible(true); } /** Gets the width of this picture. @return the width */ public int getWidth() { return image.getWidth(); } /** Gets the height of this picture. @return the height */ public int getHeight() { return image.getHeight(); } /** Loads a picture from a given source. @param source the image source. If the source starts with http://, it is a URL, otherwise, a filename. */ public void load(String source) { try { this.source = source; BufferedImage img; if (source.startsWith("http://")) img = ImageIO.read(new URL(source).openStream()); else img = ImageIO.read(new File(source)); setImage(img); } catch (Exception ex) { this.source = null; ex.printStackTrace(); } } /** Reloads this picture, undoing any manipulations. */ public void reload() { load(source); } /** Displays a file chooser for picking a picture. */ public void pick() { JFileChooser chooser = new JFileChooser("."); if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { load(chooser.getSelectedFile().getAbsolutePath()); } } /** Moves this picture by the given amount in x- and y-direction. @param dx the offset in the x-direction @param dy the offset in the y-direction */ public void move(int dx, int dy) { BufferedImageOp op = new AffineTransformOp( AffineTransform.getTranslateInstance(dx, dy), AffineTransformOp.TYPE_BILINEAR); BufferedImage filteredImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB); op.filter(image, filteredImage); setImage(filteredImage); } /** Scales this picture to a new size. If the new size is smaller than the old size, the remainder is filled with transparent pixels. If it is larger, it is clipped. @param newWidth the new width of the picture @param newHeight the new height of the picture */ public void scale(int newWidth, int newHeight) { double dx = newWidth * 1.0 / image.getWidth(); double dy = newHeight * 1.0 / image.getHeight(); BufferedImageOp op = new AffineTransformOp( AffineTransform.getScaleInstance(dx, dy), AffineTransformOp.TYPE_BILINEAR); BufferedImage filteredImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB); op.filter(image, filteredImage); setImage(filteredImage); } /** Adds a black border to the image. @param width the border width */ public void border(int width) { for (int x = 0; x < width; x++) { for (int y = 0; y < image.getHeight(); y++) { setColorAt(x, y, Color.BLACK); setColorAt(image.getWidth() - 1 - x, y, Color.BLACK); } } for (int y = 0; y < width; y++) { for (int x = width; x < image.getWidth() - width; x++) { setColorAt(x, y, Color.BLACK); setColorAt(x, image.getHeight() - 1 - y, Color.BLACK); } } } /** Gets the color of a pixel. @param x the column index (between 0 and getWidth() - 1) @param y the row index (between 0 and getHeight() - 1) @return the color of the pixel at position (x, y) */ public Color getColorAt(int x, int y) { Raster raster = image.getRaster(); ColorModel model = image.getColorModel(); int argb = model.getRGB(raster.getDataElements(x, y, null)); return new Color(argb, true); } /** Sets the color of a pixel. @param x the column index (between 0 and getWidth() - 1) @param y the row index (between 0 and getHeight() - 1) @param c the color for the pixel at position (x, y) */ public void setColorAt(int x, int y, Color c) { WritableRaster raster = image.getRaster(); ColorModel model = image.getColorModel(); Object colorData = model.getDataElements(c.getRGB(), null); raster.setDataElements(x, y, colorData); label.repaint(); } private void setImage(BufferedImage image) { this.image = image; label.setIcon(new ImageIcon(image)); label.setText(""); label.setSize(image.getWidth(), image.getHeight()); frame.pack(); } }