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 @ 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
}