gvsig-tools / org.gvsig.tools / library / trunk / org.gvsig.tools / org.gvsig.tools.swing / org.gvsig.tools.swing.impl / src / main / java / org / gvsig / tools / swing / impl / DefaultSimpleImage.java @ 2295
History | View | Annotate | Download (13.7 KB)
1 |
package org.gvsig.tools.swing.impl; |
---|---|
2 |
|
3 |
import java.awt.Dimension; |
4 |
import java.awt.Graphics2D; |
5 |
import java.awt.Image; |
6 |
import java.awt.MediaTracker; |
7 |
import java.awt.RenderingHints; |
8 |
import java.awt.geom.AffineTransform; |
9 |
import java.awt.image.BufferedImage; |
10 |
import java.io.ByteArrayInputStream; |
11 |
import java.io.ByteArrayOutputStream; |
12 |
import java.io.File; |
13 |
import java.io.FileInputStream; |
14 |
import java.io.IOException; |
15 |
import java.io.InputStream; |
16 |
import java.io.OutputStream; |
17 |
import java.net.URL; |
18 |
import java.util.Iterator; |
19 |
import javax.imageio.ImageIO; |
20 |
import javax.imageio.ImageReader; |
21 |
import javax.imageio.stream.ImageInputStream; |
22 |
import javax.swing.ImageIcon; |
23 |
import org.apache.commons.codec.DecoderException; |
24 |
import org.apache.commons.codec.binary.Base64; |
25 |
import org.apache.commons.codec.binary.Hex; |
26 |
import org.apache.commons.io.IOUtils; |
27 |
import org.apache.commons.lang3.StringUtils; |
28 |
import org.apache.commons.lang3.mutable.MutableObject; |
29 |
import org.gvsig.tools.swing.api.SimpleImage; |
30 |
|
31 |
/**
|
32 |
*
|
33 |
* @author jjdelcerro
|
34 |
*/
|
35 |
@SuppressWarnings("UseSpecificCatch") |
36 |
public class DefaultSimpleImage implements SimpleImage { |
37 |
|
38 |
private BufferedImage image; |
39 |
private Object source; |
40 |
private Dimension dimensions; |
41 |
private String formatName; |
42 |
|
43 |
public static BufferedImage toBufferedImage(Image img) { |
44 |
if( img == null ) { |
45 |
throw new IllegalArgumentException("null image."); |
46 |
} |
47 |
if (img instanceof BufferedImage) { |
48 |
return (BufferedImage) img; |
49 |
} |
50 |
// Create a buffered image with transparency
|
51 |
BufferedImage bimage = new BufferedImage( |
52 |
img.getWidth(null),
|
53 |
img.getHeight(null),
|
54 |
BufferedImage.TYPE_INT_ARGB
|
55 |
); |
56 |
// Draw the image on to the buffered image
|
57 |
Graphics2D bGr = bimage.createGraphics();
|
58 |
bGr.drawImage(img, 0, 0, null); |
59 |
bGr.dispose(); |
60 |
return bimage;
|
61 |
} |
62 |
|
63 |
public DefaultSimpleImage() {
|
64 |
this.image = null; |
65 |
this.dimensions = null; |
66 |
this.source = null; |
67 |
this.formatName = null; |
68 |
} |
69 |
|
70 |
public DefaultSimpleImage(BufferedImage image) { |
71 |
this();
|
72 |
this.image = image;
|
73 |
this.source = image;
|
74 |
} |
75 |
|
76 |
public DefaultSimpleImage(Object source) { |
77 |
this();
|
78 |
this.source = source;
|
79 |
} |
80 |
|
81 |
public void clean() { |
82 |
this.image = null; |
83 |
this.dimensions = null; |
84 |
this.source = null; |
85 |
this.formatName = null; |
86 |
} |
87 |
|
88 |
@Override
|
89 |
public BufferedImage getBufferedImage() { |
90 |
if( this.image == null ) { |
91 |
Dimension dim = new Dimension(); |
92 |
MutableObject<String> theFormatName = new MutableObject<>(null); |
93 |
this.image = this.load(source, dim, theFormatName); |
94 |
this.dimensions = dim;
|
95 |
this.formatName = theFormatName.getValue();
|
96 |
} |
97 |
return this.image; |
98 |
} |
99 |
|
100 |
@Override
|
101 |
public String getFormatName() { |
102 |
return this.formatName; |
103 |
} |
104 |
|
105 |
@Override
|
106 |
public boolean isEmpty() { |
107 |
return this.image == null && this.source==null ; |
108 |
} |
109 |
|
110 |
@Override
|
111 |
public void set(BufferedImage image) { |
112 |
this.image = image;
|
113 |
this.source = image;
|
114 |
} |
115 |
|
116 |
@Override
|
117 |
public void set(Object source) { |
118 |
this.image = null; |
119 |
this.source = source;
|
120 |
} |
121 |
|
122 |
private BufferedImage load(Object source, Dimension dimensions, MutableObject<String> formatName) { |
123 |
BufferedImage theImage = null; |
124 |
if( formatName!=null ) { |
125 |
formatName.setValue(null);
|
126 |
} |
127 |
try {
|
128 |
if (source instanceof BufferedImage) { |
129 |
theImage = (BufferedImage) source;
|
130 |
|
131 |
} else if (source instanceof ImageIcon ) { |
132 |
ImageIcon icon = (ImageIcon)source; |
133 |
int loadStatus = icon.getImageLoadStatus();
|
134 |
if( loadStatus != MediaTracker.COMPLETE ) { |
135 |
icon.getDescription(); |
136 |
} |
137 |
theImage = toBufferedImage(icon.getImage()); |
138 |
|
139 |
} else if (source instanceof Image) { |
140 |
theImage = toBufferedImage((Image) source);
|
141 |
|
142 |
} else if (source instanceof byte[]) { |
143 |
ByteArrayInputStream is = new ByteArrayInputStream((byte[]) source); |
144 |
theImage = ImageIO.read(is);
|
145 |
if( formatName!=null ) { |
146 |
formatName.setValue(this.getFormatName(source));
|
147 |
} |
148 |
|
149 |
} else if (source instanceof File) { |
150 |
theImage = ImageIO.read((File) source); |
151 |
if( formatName!=null ) { |
152 |
formatName.setValue(this.getFormatName(source));
|
153 |
} |
154 |
|
155 |
} else if (source instanceof URL) { |
156 |
theImage = ImageIO.read((URL) source); |
157 |
if( formatName!=null ) { |
158 |
formatName.setValue(this.getFormatName(source));
|
159 |
} |
160 |
|
161 |
} else if (source instanceof String) { |
162 |
InputStream is;
|
163 |
String s = (String) source; |
164 |
File f = new File(s); |
165 |
byte[] data = null; |
166 |
if (f.exists()) {
|
167 |
is = new FileInputStream(f); |
168 |
} else {
|
169 |
try {
|
170 |
URL url = new URL(s); |
171 |
is = url.openStream(); |
172 |
is.available(); // Force exception if is null
|
173 |
} catch (Exception ex) { |
174 |
try {
|
175 |
data = Hex.decodeHex(s.toCharArray()); |
176 |
is = new ByteArrayInputStream(data); |
177 |
} catch (DecoderException ex2) {
|
178 |
try {
|
179 |
data = Base64.decodeBase64(s); |
180 |
is = new ByteArrayInputStream(data); |
181 |
} catch (Exception ex3) { |
182 |
return null; |
183 |
} |
184 |
} |
185 |
} |
186 |
} |
187 |
theImage = ImageIO.read(is);
|
188 |
IOUtils.closeQuietly(is); |
189 |
if( formatName!=null && data!=null ) { |
190 |
formatName.setValue(this.getFormatName(data));
|
191 |
} |
192 |
} |
193 |
} catch (IOException ex) { |
194 |
return null; |
195 |
} |
196 |
if( theImage!=null && dimensions!=null ) { |
197 |
dimensions.width = theImage.getWidth(); |
198 |
dimensions.height = theImage.getHeight(); |
199 |
} |
200 |
return theImage;
|
201 |
} |
202 |
|
203 |
private String getFormatName(Object source) { |
204 |
try {
|
205 |
ImageInputStream in = ImageIO.createImageInputStream(source); |
206 |
Iterator<ImageReader> readers = ImageIO.getImageReaders(in); |
207 |
if (readers!=null && readers.hasNext()) { |
208 |
ImageReader reader = readers.next();
|
209 |
try {
|
210 |
reader.setInput(in); |
211 |
return reader.getFormatName();
|
212 |
} finally {
|
213 |
reader.dispose(); |
214 |
} |
215 |
} |
216 |
return null; |
217 |
} catch (IOException ex) { |
218 |
throw new RuntimeException("Can't determine format name of the image.", ex); |
219 |
} |
220 |
} |
221 |
|
222 |
private Dimension loadDimensions(Object source) { |
223 |
try {
|
224 |
ImageInputStream in = ImageIO.createImageInputStream(source); |
225 |
Iterator<ImageReader> readers = ImageIO.getImageReaders(in); |
226 |
if (readers!=null && readers.hasNext()) { |
227 |
ImageReader reader = readers.next();
|
228 |
try {
|
229 |
reader.setInput(in); |
230 |
return new Dimension(reader.getWidth(0), reader.getHeight(0)); |
231 |
} finally {
|
232 |
reader.dispose(); |
233 |
} |
234 |
} |
235 |
Dimension dim = new Dimension(); |
236 |
this.image = this.load(source, dim, null); |
237 |
return dim;
|
238 |
} catch (IOException ex) { |
239 |
throw new RuntimeException("Can't load dimensions of the image.", ex); |
240 |
} |
241 |
} |
242 |
|
243 |
@Override
|
244 |
public int getWidth() { |
245 |
if( this.dimensions == null ) { |
246 |
this.dimensions = this.loadDimensions(source); |
247 |
} |
248 |
return this.dimensions.width; |
249 |
} |
250 |
|
251 |
@Override
|
252 |
public int getHeight() { |
253 |
if( this.dimensions == null ) { |
254 |
this.dimensions = this.loadDimensions(source); |
255 |
} |
256 |
return this.dimensions.height; |
257 |
} |
258 |
|
259 |
@Override
|
260 |
public DefaultSimpleImage resize(double factor) { |
261 |
BufferedImage theImage = this.getBufferedImage(); |
262 |
int w = theImage.getWidth();
|
263 |
int h = theImage.getHeight();
|
264 |
int width = (int) (w * factor); |
265 |
int height = (int) (h * factor); |
266 |
BufferedImage newImage = new BufferedImage(width, height, theImage.getType()); |
267 |
Graphics2D g = newImage.createGraphics();
|
268 |
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); |
269 |
g.drawImage(theImage, 0, 0, width, height, 0, 0, w, h, null); |
270 |
g.dispose(); |
271 |
return new DefaultSimpleImage(newImage); |
272 |
} |
273 |
|
274 |
@Override
|
275 |
public DefaultSimpleImage resize(int width, int height) { |
276 |
BufferedImage theImage = this.getBufferedImage(); |
277 |
int w = theImage.getWidth();
|
278 |
int h = theImage.getHeight();
|
279 |
BufferedImage newImage = new BufferedImage(width, height, theImage.getType()); |
280 |
Graphics2D g = newImage.createGraphics();
|
281 |
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); |
282 |
g.drawImage(theImage, 0, 0, width, height, 0, 0, w, h, null); |
283 |
g.dispose(); |
284 |
return new DefaultSimpleImage(newImage); |
285 |
} |
286 |
|
287 |
@Override
|
288 |
public DefaultSimpleImage rotate(int angle) { |
289 |
BufferedImage theImage = this.getBufferedImage(); |
290 |
int w = theImage.getWidth();
|
291 |
int h = theImage.getHeight();
|
292 |
BufferedImage newImage = new BufferedImage(w, h, theImage.getType()); |
293 |
Graphics2D g = newImage.createGraphics();
|
294 |
g.rotate(Math.toRadians(angle), w / 2, h / 2); |
295 |
g.drawImage(theImage, null, 0, 0); |
296 |
g.dispose(); |
297 |
return new DefaultSimpleImage(newImage); |
298 |
} |
299 |
|
300 |
@Override
|
301 |
public DefaultSimpleImage horizontalflip() {
|
302 |
BufferedImage img = this.getBufferedImage(); |
303 |
int w = img.getWidth();
|
304 |
int h = img.getHeight();
|
305 |
BufferedImage newImage = new BufferedImage(w, h, img.getType()); |
306 |
Graphics2D g = newImage.createGraphics();
|
307 |
g.drawImage(img, 0, 0, w, h, w, 0, 0, h, null); |
308 |
g.dispose(); |
309 |
return new DefaultSimpleImage(newImage); |
310 |
} |
311 |
|
312 |
@Override
|
313 |
public DefaultSimpleImage verticalflip() {
|
314 |
BufferedImage img = this.getBufferedImage(); |
315 |
int w = img.getWidth();
|
316 |
int h = img.getHeight();
|
317 |
BufferedImage newImage = new BufferedImage(w, h, img.getColorModel().getTransparency()); |
318 |
Graphics2D g = newImage.createGraphics();
|
319 |
g.drawImage(img, 0, 0, w, h, 0, h, w, 0, null); |
320 |
g.dispose(); |
321 |
return new DefaultSimpleImage(newImage); |
322 |
} |
323 |
|
324 |
@Override
|
325 |
public DefaultSimpleImage transform(AffineTransform transform, int width, int height) { |
326 |
BufferedImage img = this.getBufferedImage(); |
327 |
BufferedImage newImage = new BufferedImage(width, height, img.getColorModel().getTransparency()); |
328 |
Graphics2D g = newImage.createGraphics();
|
329 |
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); |
330 |
g.setTransform(transform); |
331 |
g.drawImage(img, 0, 0, null); |
332 |
g.dispose(); |
333 |
return new DefaultSimpleImage(newImage); |
334 |
} |
335 |
|
336 |
@Override
|
337 |
public DefaultSimpleImage transform(AffineTransform transform) { |
338 |
BufferedImage img = this.getBufferedImage(); |
339 |
int w = img.getWidth();
|
340 |
int h = img.getHeight();
|
341 |
BufferedImage newImage = new BufferedImage(w, h, img.getColorModel().getTransparency()); |
342 |
Graphics2D g = newImage.createGraphics();
|
343 |
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); |
344 |
g.setTransform(transform); |
345 |
g.drawImage(img, 0, 0, null); |
346 |
g.dispose(); |
347 |
return new DefaultSimpleImage(newImage); |
348 |
} |
349 |
|
350 |
private String bytearray_hex(byte[] data) { |
351 |
StringBuilder builder = new StringBuilder(); |
352 |
for (byte abyte : data) { |
353 |
int v = abyte & 0xff; |
354 |
builder.append(String.format("%02x", v)); |
355 |
} |
356 |
return builder.toString();
|
357 |
} |
358 |
|
359 |
@Override
|
360 |
public byte[] toBytearray() { |
361 |
return toBytearray(null); |
362 |
} |
363 |
|
364 |
@Override
|
365 |
public byte[] toBytearray(String format) { |
366 |
try {
|
367 |
if( StringUtils.isBlank(format) ) {
|
368 |
format = this.formatName==null?"png":this.formatName; |
369 |
} |
370 |
ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
371 |
ImageIO.write( this.getBufferedImage(), format, baos ); |
372 |
baos.flush(); |
373 |
byte[] imageInByte = baos.toByteArray(); |
374 |
baos.close(); |
375 |
return imageInByte;
|
376 |
} catch (IOException ex) { |
377 |
return null; |
378 |
} |
379 |
} |
380 |
|
381 |
@Override
|
382 |
public String toString() { |
383 |
byte[] data = this.toBytearray(); |
384 |
return bytearray_hex(data);
|
385 |
} |
386 |
|
387 |
@Override
|
388 |
public String toString(String format) { |
389 |
byte[] data = this.toBytearray(format); |
390 |
return bytearray_hex(data);
|
391 |
} |
392 |
|
393 |
@Override
|
394 |
public void save(File output, String formatName) throws IOException { |
395 |
if( StringUtils.isBlank(formatName) ) {
|
396 |
formatName = this.formatName==null?"png":this.formatName; |
397 |
} |
398 |
ImageIO.write(this.getBufferedImage(), formatName, output); |
399 |
} |
400 |
|
401 |
@Override
|
402 |
public void save(OutputStream output, String formatName) throws IOException { |
403 |
if( StringUtils.isBlank(formatName) ) {
|
404 |
formatName = this.formatName==null?"png":this.formatName; |
405 |
} |
406 |
ImageIO.write(this.getBufferedImage(), formatName, output); |
407 |
} |
408 |
|
409 |
} |