PageRenderTime 42ms CodeModel.GetById 30ms app.highlight 8ms RepoModel.GetById 2ms app.codeStats 0ms

/src/mpv5/utils/images/MPIcon.java

http://mp-rechnungs-und-kundenverwaltung.googlecode.com/
Java | 338 lines | 170 code | 33 blank | 135 comment | 23 complexity | 3e4dd2481d382621b04f07a6e98a0227 MD5 | raw file
  1/*
  2 *  This file is part of YaBS.
  3 *
  4 *      YaBS is free software: you can redistribute it and/or modify
  5 *      it under the terms of the GNU General Public License as published by
  6 *      the Free Software Foundation, either version 3 of the License, or
  7 *      (at your option) any later version.
  8 *
  9 *      YaBS is distributed in the hope that it will be useful,
 10 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 11 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12 *      GNU General Public License for more details.
 13 *
 14 *      You should have received a copy of the GNU General Public License
 15 *      along with YaBS.  If not, see <http://www.gnu.org/licenses/>.
 16 */
 17package mpv5.utils.images;
 18
 19import java.awt.Component;
 20import java.awt.Graphics;
 21import java.awt.Graphics2D;
 22import java.awt.GraphicsConfiguration;
 23import java.awt.GraphicsDevice;
 24import java.awt.GraphicsEnvironment;
 25import java.awt.HeadlessException;
 26import java.awt.Image;
 27import java.awt.RenderingHints;
 28import java.awt.Transparency;
 29import java.awt.image.BufferedImage;
 30import java.awt.image.ColorModel;
 31import java.awt.image.PixelGrabber;
 32import java.net.URL;
 33import java.util.HashMap;
 34import javax.swing.Icon;
 35import javax.swing.ImageIcon;
 36import mpv5.logging.Log;
 37
 38/**
 39 *
 40 */
 41public class MPIcon extends ImageIcon {
 42
 43    private static final long serialVersionUID = 1L;
 44    public static String DIRECTORY_DEFAULT_ICONS = "/mpv5/resources/images/22/mimetypes/";
 45    public static Icon ICON_ENABLED = new javax.swing.ImageIcon(MPIcon.class.getResource("/mpv5/resources/images/16/yes.png"));
 46
 47
 48    /**
 49     *
 50     * @param icon
 51     */
 52    public MPIcon(Icon icon) {
 53        super(iconToImage(icon));
 54    }
 55
 56    /**
 57     * 
 58     * @param icon
 59     */
 60    public MPIcon(ImageIcon icon) {
 61        super(icon.getImage());
 62    }
 63
 64    /**
 65     * 
 66     * @param icon
 67     */
 68    public MPIcon(Image icon) {
 69        super(icon);
 70    }
 71
 72    /**
 73     * Internal resources only!
 74     * @param resource
 75     */
 76    public MPIcon(String resource) {
 77        super(MPIcon.class.getResource(resource));
 78    }
 79
 80     /**
 81      *  @param pathToImage
 82      */
 83    public MPIcon(URL pathToImage) {
 84        super(pathToImage);
 85    }
 86
 87    private MPIcon() {
 88        super();
 89    }
 90
 91    /**
 92     *
 93     * @param icon
 94     * @return
 95     */
 96    public static Image iconToImage(Icon icon) {
 97        if (icon instanceof ImageIcon) {
 98            return ((ImageIcon) icon).getImage();
 99        } else {
100            int w = icon.getIconWidth();
101            int h = icon.getIconHeight();
102            GraphicsEnvironment ge =
103                    GraphicsEnvironment.getLocalGraphicsEnvironment();
104            GraphicsDevice gd = ge.getDefaultScreenDevice();
105            GraphicsConfiguration gc = gd.getDefaultConfiguration();
106            BufferedImage image = gc.createCompatibleImage(w, h);
107            Graphics2D g = image.createGraphics();
108            icon.paintIcon(null, g, 0, 0);
109            g.dispose();
110            return image;
111        }
112    }
113
114//    /**
115//     * Paints the icon.
116//     * The top-left corner of the icon is drawn at
117//     * the point (<code>x</code>, <code>y</code>)
118//     * in the coordinate space of the graphics context <code>g</code>.
119//     * If this icon has no image observer,
120//     * this method uses the <code>c</code> component
121//     * as the observer.
122//     *
123//     * @param c the component to be used as the observer
124//     *          if this icon has no image observer
125//     * @param g the graphics context
126//     * @param x the X coordinate of the icon's top-left corner
127//     * @param y the Y coordinate of the icon's top-left corner
128//     */
129//    @Override
130//    public synchronized void paintIcon(Component c, Graphics g, int x, int y) {
131//        Image image = getImage();
132//        if (super.getImageObserver() == null) {
133//            g.drawImage(image, x, y, c);
134//        } else {
135//            g.drawImage(image, x, y, super.getImageObserver());
136//        }
137//    }
138
139    /**
140     * Creates an Icon with the specified size, fast and ugly
141     * @param maxWidthHeigth
142     * @return
143     */
144    public Icon getIcon(int maxWidthHeigth) {
145        return getIcon(maxWidthHeigth, -1);
146    }
147
148    /**
149     * Creates an Icon with the specified size, nice but slowly
150     * @param maxWidth
151     * @param maxHeight
152     * @return
153     */
154    public Icon getIcon(int maxWidth, int maxHeight) {
155        if (!cache.containsKey(maxWidth + "@" + maxHeight)) {
156            BufferedImage bi = toBufferedImage(this.getImage());
157            bi = getScaledInstance(bi, maxWidth, maxHeight, RenderingHints.VALUE_INTERPOLATION_BILINEAR, maxHeight > 0);
158            MPIcon imic = new MPIcon(bi);
159            cache.put(maxWidth + "@" + maxHeight, imic);
160            return imic;
161        } else {
162            return cache.get(maxWidth + "@" + maxHeight);
163        }
164    }
165    private HashMap<String, MPIcon> cache = new HashMap<String, MPIcon>();
166
167    /**
168     * Convenience method that returns a scaled instance of the
169     * provided {@code BufferedImage}.
170     *
171     * @param img the original image to be scaled
172     * @param targetWidth the desired width of the scaled instance,
173     *    in pixels
174     * @param targetHeight the desired height of the scaled instance,
175     *    in pixels
176     * @param hint one of the rendering hints that corresponds to
177     *    {@code RenderingHints.KEY_INTERPOLATION} (e.g.
178     *    {@code RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR},
179     *    {@code RenderingHints.VALUE_INTERPOLATION_BILINEAR},
180     *    {@code RenderingHints.VALUE_INTERPOLATION_BICUBIC})
181     * @param higherQuality if true, this method will use a multi-step
182     *    scaling technique that provides higher quality than the usual
183     *    one-step technique (only useful in downscaling cases, where
184     *    {@code targetWidth} or {@code targetHeight} is
185     *    smaller than the original dimensions, and generally only when
186     *    the {@code BILINEAR} hint is specified)
187     * @return a scaled version of the original {@code BufferedImage}
188     */
189    public static BufferedImage getScaledInstance(BufferedImage img,
190            int targetWidth,
191            int targetHeight,
192            Object hint,
193            boolean higherQuality) {
194        int type = (img.getTransparency() == Transparency.OPAQUE) ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
195        BufferedImage ret = img;
196        int w, h;
197        if (higherQuality) {
198            // Use multi-step technique: start with original size, then
199            // scale down in multiple passes with drawImage()
200            // until the target size is reached
201            w = img.getWidth();
202            h = img.getHeight();
203        } else {
204            return toBufferedImage(img.getScaledInstance(targetWidth, -1, BufferedImage.SCALE_SMOOTH));
205        }
206
207        do {
208            if (higherQuality && w > targetWidth) {
209                w /= 2;
210                if (w < targetWidth) {
211                    w = targetWidth;
212                }
213            }
214
215            if (higherQuality && h > targetHeight) {
216                h /= 2;
217                if (h < targetHeight) {
218                    h = targetHeight;
219                }
220            }
221
222            BufferedImage tmp = new BufferedImage(w, h, type);
223            Graphics2D g2 = tmp.createGraphics();
224            g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
225            g2.drawImage(ret, 0, 0, w, h, null);
226            g2.dispose();
227
228            ret = tmp;
229        } while (w > targetWidth || h > targetHeight);
230
231        return ret;
232    }
233
234    //
235    /**
236     * This method returns a buffered image with the contents of an image
237     * @param image
238     * @return
239     */
240    public static BufferedImage toBufferedImage(Image image) {
241        if (image instanceof BufferedImage) {
242            return (BufferedImage) image;
243        }
244
245        // This code ensures that all the pixels in the image are loaded
246        image = new ImageIcon(image).getImage();
247
248        // Determine if the image has transparent pixels; for this method's
249        // implementation, see e661 Determining If an Image Has Transparent Pixels
250        boolean hasAlpha = false;
251        try {
252            hasAlpha = hasAlpha(image);
253        } catch (Exception e) {
254            Log.Debug(MPIcon.class, "Could not determine alpha of image: " + image);
255        }
256
257        // Create a buffered image with a format that's compatible with the screen
258        BufferedImage bimage = null;
259        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
260        try {
261            // Determine the type of transparency of the new buffered image
262            int transparency = Transparency.OPAQUE;
263            if (hasAlpha) {
264                transparency = Transparency.BITMASK;
265            }
266
267            // Create the buffered image
268            GraphicsDevice gs = ge.getDefaultScreenDevice();
269            GraphicsConfiguration gc = gs.getDefaultConfiguration();
270            bimage = gc.createCompatibleImage(
271                    image.getWidth(null), image.getHeight(null), transparency);
272        } catch (HeadlessException e) {
273            // The system does not have a screen
274        }
275
276        if (bimage == null) {
277            // Create a buffered image using the default color model
278            int type = BufferedImage.TYPE_INT_RGB;
279            if (hasAlpha) {
280                type = BufferedImage.TYPE_INT_ARGB;
281            }
282            bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type);
283        }
284
285        // Copy image to buffered image
286        Graphics g = bimage.createGraphics();
287
288        // Paint the image onto the buffered image
289        g.drawImage(image, 0, 0, null);
290        g.dispose();
291
292        return bimage;
293    }
294
295    // 
296    /**
297     * This method returns true if the specified image has transparent pixels
298     * @param image
299     * @return
300     */
301    public static boolean hasAlpha(Image image) {
302        // If buffered image, the color model is readily available
303        if (image instanceof BufferedImage) {
304            BufferedImage bimage = (BufferedImage) image;
305            return bimage.getColorModel().hasAlpha();
306        }
307
308        // Use a pixel grabber to retrieve the image's color model;
309        // grabbing a single pixel is usually sufficient
310        PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false);
311        try {
312            pg.grabPixels();
313        } catch (InterruptedException e) {
314        }
315
316        // Get the image's color model
317        ColorModel cm = pg.getColorModel();
318        return cm.hasAlpha();
319    }
320
321    /**
322     * Scale the image of this icon
323     * @param width
324     * @param height
325     * @return
326     */
327    public MPIcon getScaledIcon(int maxWidth, int maxHeight) {
328        if (!cache.containsKey(maxWidth + "@" + maxHeight)) {
329            BufferedImage bi = toBufferedImage(this.getImage());
330            bi = getScaledInstance(bi, maxWidth, maxHeight, RenderingHints.VALUE_INTERPOLATION_BILINEAR, maxHeight > 0);
331            MPIcon imic = new MPIcon(bi);
332            cache.put(maxWidth + "@" + maxHeight, imic);
333            return imic;
334        } else {
335            return cache.get(maxWidth + "@" + maxHeight);
336        }
337    }
338}