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 @ 2298
History | View | Annotate | Download (13.8 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 |
if (in==null) { |
207 |
return null; |
208 |
} |
209 |
Iterator<ImageReader> readers = ImageIO.getImageReaders(in); |
210 |
if (readers!=null && readers.hasNext()) { |
211 |
ImageReader reader = readers.next();
|
212 |
try {
|
213 |
reader.setInput(in); |
214 |
return reader.getFormatName();
|
215 |
} finally {
|
216 |
reader.dispose(); |
217 |
} |
218 |
} |
219 |
return null; |
220 |
} catch (Exception ex) { |
221 |
throw new RuntimeException("Can't determine format name of the image.", ex); |
222 |
} |
223 |
} |
224 |
|
225 |
private Dimension loadDimensions(Object source) { |
226 |
try {
|
227 |
ImageInputStream in = ImageIO.createImageInputStream(source); |
228 |
Iterator<ImageReader> readers = ImageIO.getImageReaders(in); |
229 |
if (readers!=null && readers.hasNext()) { |
230 |
ImageReader reader = readers.next();
|
231 |
try {
|
232 |
reader.setInput(in); |
233 |
return new Dimension(reader.getWidth(0), reader.getHeight(0)); |
234 |
} finally {
|
235 |
reader.dispose(); |
236 |
} |
237 |
} |
238 |
Dimension dim = new Dimension(); |
239 |
this.image = this.load(source, dim, null); |
240 |
return dim;
|
241 |
} catch (IOException ex) { |
242 |
throw new RuntimeException("Can't load dimensions of the image.", ex); |
243 |
} |
244 |
} |
245 |
|
246 |
@Override
|
247 |
public int getWidth() { |
248 |
if( this.dimensions == null ) { |
249 |
this.dimensions = this.loadDimensions(source); |
250 |
} |
251 |
return this.dimensions.width; |
252 |
} |
253 |
|
254 |
@Override
|
255 |
public int getHeight() { |
256 |
if( this.dimensions == null ) { |
257 |
this.dimensions = this.loadDimensions(source); |
258 |
} |
259 |
return this.dimensions.height; |
260 |
} |
261 |
|
262 |
@Override
|
263 |
public DefaultSimpleImage resize(double factor) { |
264 |
BufferedImage theImage = this.getBufferedImage(); |
265 |
int w = theImage.getWidth();
|
266 |
int h = theImage.getHeight();
|
267 |
int width = (int) (w * factor); |
268 |
int height = (int) (h * factor); |
269 |
BufferedImage newImage = new BufferedImage(width, height, theImage.getType()); |
270 |
Graphics2D g = newImage.createGraphics();
|
271 |
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); |
272 |
g.drawImage(theImage, 0, 0, width, height, 0, 0, w, h, null); |
273 |
g.dispose(); |
274 |
return new DefaultSimpleImage(newImage); |
275 |
} |
276 |
|
277 |
@Override
|
278 |
public DefaultSimpleImage resize(int width, int height) { |
279 |
BufferedImage theImage = this.getBufferedImage(); |
280 |
int w = theImage.getWidth();
|
281 |
int h = theImage.getHeight();
|
282 |
BufferedImage newImage = new BufferedImage(width, height, theImage.getType()); |
283 |
Graphics2D g = newImage.createGraphics();
|
284 |
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); |
285 |
g.drawImage(theImage, 0, 0, width, height, 0, 0, w, h, null); |
286 |
g.dispose(); |
287 |
return new DefaultSimpleImage(newImage); |
288 |
} |
289 |
|
290 |
@Override
|
291 |
public DefaultSimpleImage rotate(int angle) { |
292 |
BufferedImage theImage = this.getBufferedImage(); |
293 |
int w = theImage.getWidth();
|
294 |
int h = theImage.getHeight();
|
295 |
BufferedImage newImage = new BufferedImage(w, h, theImage.getType()); |
296 |
Graphics2D g = newImage.createGraphics();
|
297 |
g.rotate(Math.toRadians(angle), w / 2, h / 2); |
298 |
g.drawImage(theImage, null, 0, 0); |
299 |
g.dispose(); |
300 |
return new DefaultSimpleImage(newImage); |
301 |
} |
302 |
|
303 |
@Override
|
304 |
public DefaultSimpleImage horizontalflip() {
|
305 |
BufferedImage img = this.getBufferedImage(); |
306 |
int w = img.getWidth();
|
307 |
int h = img.getHeight();
|
308 |
BufferedImage newImage = new BufferedImage(w, h, img.getType()); |
309 |
Graphics2D g = newImage.createGraphics();
|
310 |
g.drawImage(img, 0, 0, w, h, w, 0, 0, h, null); |
311 |
g.dispose(); |
312 |
return new DefaultSimpleImage(newImage); |
313 |
} |
314 |
|
315 |
@Override
|
316 |
public DefaultSimpleImage verticalflip() {
|
317 |
BufferedImage img = this.getBufferedImage(); |
318 |
int w = img.getWidth();
|
319 |
int h = img.getHeight();
|
320 |
BufferedImage newImage = new BufferedImage(w, h, img.getColorModel().getTransparency()); |
321 |
Graphics2D g = newImage.createGraphics();
|
322 |
g.drawImage(img, 0, 0, w, h, 0, h, w, 0, null); |
323 |
g.dispose(); |
324 |
return new DefaultSimpleImage(newImage); |
325 |
} |
326 |
|
327 |
@Override
|
328 |
public DefaultSimpleImage transform(AffineTransform transform, int width, int height) { |
329 |
BufferedImage img = this.getBufferedImage(); |
330 |
BufferedImage newImage = new BufferedImage(width, height, img.getColorModel().getTransparency()); |
331 |
Graphics2D g = newImage.createGraphics();
|
332 |
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); |
333 |
g.setTransform(transform); |
334 |
g.drawImage(img, 0, 0, null); |
335 |
g.dispose(); |
336 |
return new DefaultSimpleImage(newImage); |
337 |
} |
338 |
|
339 |
@Override
|
340 |
public DefaultSimpleImage transform(AffineTransform transform) { |
341 |
BufferedImage img = this.getBufferedImage(); |
342 |
int w = img.getWidth();
|
343 |
int h = img.getHeight();
|
344 |
BufferedImage newImage = new BufferedImage(w, h, img.getColorModel().getTransparency()); |
345 |
Graphics2D g = newImage.createGraphics();
|
346 |
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); |
347 |
g.setTransform(transform); |
348 |
g.drawImage(img, 0, 0, null); |
349 |
g.dispose(); |
350 |
return new DefaultSimpleImage(newImage); |
351 |
} |
352 |
|
353 |
private String bytearray_hex(byte[] data) { |
354 |
StringBuilder builder = new StringBuilder(); |
355 |
for (byte abyte : data) { |
356 |
int v = abyte & 0xff; |
357 |
builder.append(String.format("%02x", v)); |
358 |
} |
359 |
return builder.toString();
|
360 |
} |
361 |
|
362 |
@Override
|
363 |
public byte[] toBytearray() { |
364 |
return toBytearray(null); |
365 |
} |
366 |
|
367 |
@Override
|
368 |
public byte[] toBytearray(String format) { |
369 |
try {
|
370 |
if( StringUtils.isBlank(format) ) {
|
371 |
format = this.formatName==null?"png":this.formatName; |
372 |
} |
373 |
ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
374 |
ImageIO.write( this.getBufferedImage(), format, baos ); |
375 |
baos.flush(); |
376 |
byte[] imageInByte = baos.toByteArray(); |
377 |
baos.close(); |
378 |
return imageInByte;
|
379 |
} catch (IOException ex) { |
380 |
return null; |
381 |
} |
382 |
} |
383 |
|
384 |
@Override
|
385 |
public String toString() { |
386 |
byte[] data = this.toBytearray(); |
387 |
return bytearray_hex(data);
|
388 |
} |
389 |
|
390 |
@Override
|
391 |
public String toString(String format) { |
392 |
byte[] data = this.toBytearray(format); |
393 |
return bytearray_hex(data);
|
394 |
} |
395 |
|
396 |
@Override
|
397 |
public void save(File output, String formatName) throws IOException { |
398 |
if( StringUtils.isBlank(formatName) ) {
|
399 |
formatName = this.formatName==null?"png":this.formatName; |
400 |
} |
401 |
ImageIO.write(this.getBufferedImage(), formatName, output); |
402 |
} |
403 |
|
404 |
@Override
|
405 |
public void save(OutputStream output, String formatName) throws IOException { |
406 |
if( StringUtils.isBlank(formatName) ) {
|
407 |
formatName = this.formatName==null?"png":this.formatName; |
408 |
} |
409 |
ImageIO.write(this.getBufferedImage(), formatName, output); |
410 |
} |
411 |
|
412 |
} |