1 import java.awt.Color;
2 import java.io.File;
3 import java.net.URL;
4 import java.awt.geom.AffineTransform;
5 import java.awt.image.AffineTransformOp;
6 import java.awt.image.BufferedImage;
7 import java.awt.image.BufferedImageOp;
8 import java.awt.image.ColorModel;
9 import java.awt.image.Raster;
10 import java.awt.image.WritableRaster;
11 import javax.imageio.ImageIO;
12 import javax.swing.ImageIcon;
13 import javax.swing.JFileChooser;
14 import javax.swing.JFrame;
15 import javax.swing.JLabel;
16
17 /**
18 * This class allows you to view and edit pictures.
19 */
20 public class Picture
21 {
22 private String source;
23 private JFrame frame;
24 private JLabel label;
25 private BufferedImage image;
26
27 /**
28 Constructs a blank picture.
29 */
30 public Picture()
31 {
32 frame = new JFrame();
33 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
34 label = new JLabel("(No image)");
35 frame.add(label);
36 frame.pack();
37 frame.setVisible(true);
38 }
39
40 /**
41 Gets the width of this picture.
42 @return the width
43 */
44 public int getWidth() { return image.getWidth(); }
45
46 /**
47 Gets the height of this picture.
48 @return the height
49 */
50 public int getHeight() { return image.getHeight(); }
51
52 /**
53 Loads a picture from a given source.
54 @param source the image source. If the source starts
55 with http://, it is a URL, otherwise, a filename.
56 */
57 public void load(String source)
58 {
59 try
60 {
61 this.source = source;
62 BufferedImage img;
63 if (source.startsWith("http://"))
64 img = ImageIO.read(new URL(source).openStream());
65 else
66 img = ImageIO.read(new File(source));
67
68 setImage(img);
69 }
70 catch (Exception ex)
71 {
72 this.source = null;
73 ex.printStackTrace();
74 }
75 }
76
77 /**
78 Reloads this picture, undoing any manipulations.
79 */
80 public void reload()
81 {
82 load(source);
83 }
84
85 /**
86 Displays a file chooser for picking a picture.
87 */
88 public void pick()
89 {
90 JFileChooser chooser = new JFileChooser(".");
91 if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION)
92 {
93 load(chooser.getSelectedFile().getAbsolutePath());
94 }
95 }
96
97 /**
98 Moves this picture by the given amount in x- and y-direction.
99 @param dx the offset in the x-direction
100 @param dy the offset in the y-direction
101 */
102 public void move(int dx, int dy)
103 {
104 BufferedImageOp op = new AffineTransformOp(
105 AffineTransform.getTranslateInstance(dx, dy),
106 AffineTransformOp.TYPE_BILINEAR);
107 BufferedImage filteredImage
108 = new BufferedImage(image.getWidth(), image.getHeight(),
109 BufferedImage.TYPE_INT_ARGB);
110 op.filter(image, filteredImage);
111 setImage(filteredImage);
112 }
113
114 /**
115 Scales this picture to a new size. If the new size is smaller
116 than the old size, the remainder is filled with transparent
117 pixels. If it is larger, it is clipped.
118 @param newWidth the new width of the picture
119 @param newHeight the new height of the picture
120 */
121 public void scale(int newWidth, int newHeight)
122 {
123 double dx = newWidth * 1.0 / image.getWidth();
124 double dy = newHeight * 1.0 / image.getHeight();
125 BufferedImageOp op = new AffineTransformOp(
126 AffineTransform.getScaleInstance(dx, dy),
127 AffineTransformOp.TYPE_BILINEAR);
128 BufferedImage filteredImage
129 = new BufferedImage(image.getWidth(), image.getHeight(),
130 BufferedImage.TYPE_INT_ARGB);
131 op.filter(image, filteredImage);
132 setImage(filteredImage);
133 }
134
135 /**
136 Adds a black border to the image.
137 @param width the border width
138 */
139 public void border(int width)
140 {
141 for (int x = 0; x < width; x++)
142 {
143 for (int y = 0; y < image.getHeight(); y++)
144 {
145 setColorAt(x, y, Color.BLACK);
146 setColorAt(image.getWidth() - 1 - x, y, Color.BLACK);
147 }
148 }
149 for (int y = 0; y < width; y++)
150 {
151 for (int x = width; x < image.getWidth() - width; x++)
152 {
153 setColorAt(x, y, Color.BLACK);
154 setColorAt(x, image.getHeight() - 1 - y, Color.BLACK);
155 }
156 }
157 }
158
159 /**
160 Gets the color of a pixel.
161 @param x the column index (between 0 and getWidth() - 1)
162 @param y the row index (between 0 and getHeight() - 1)
163 @return the color of the pixel at position (x, y)
164 */
165 public Color getColorAt(int x, int y)
166 {
167 Raster raster = image.getRaster();
168 ColorModel model = image.getColorModel();
169 int argb = model.getRGB(raster.getDataElements(x, y, null));
170 return new Color(argb, true);
171 }
172
173 /**
174 Sets the color of a pixel.
175 @param x the column index (between 0 and getWidth() - 1)
176 @param y the row index (between 0 and getHeight() - 1)
177 @param c the color for the pixel at position (x, y)
178 */
179 public void setColorAt(int x, int y, Color c)
180 {
181 WritableRaster raster = image.getRaster();
182 ColorModel model = image.getColorModel();
183 Object colorData = model.getDataElements(c.getRGB(), null);
184 raster.setDataElements(x, y, colorData);
185 label.repaint();
186 }
187
188 private void setImage(BufferedImage image)
189 {
190 this.image = image;
191 label.setIcon(new ImageIcon(image));
192 label.setText("");
193 label.setSize(image.getWidth(), image.getHeight());
194 frame.pack();
195 }
196 }