Statistics
| Revision:

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
}