001    //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/ogcwebservices/wpvs/utils/ImageUtils.java $
002    /*----------------------------------------------------------------------------
003     This file is part of deegree, http://deegree.org/
004     Copyright (C) 2001-2009 by:
005       Department of Geography, University of Bonn
006     and
007       lat/lon GmbH
008    
009     This library is free software; you can redistribute it and/or modify it under
010     the terms of the GNU Lesser General Public License as published by the Free
011     Software Foundation; either version 2.1 of the License, or (at your option)
012     any later version.
013     This library is distributed in the hope that it will be useful, but WITHOUT
014     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
015     FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
016     details.
017     You should have received a copy of the GNU Lesser General Public License
018     along with this library; if not, write to the Free Software Foundation, Inc.,
019     59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020    
021     Contact information:
022    
023     lat/lon GmbH
024     Aennchenstr. 19, 53177 Bonn
025     Germany
026     http://lat-lon.de/
027    
028     Department of Geography, University of Bonn
029     Prof. Dr. Klaus Greve
030     Postfach 1147, 53001 Bonn
031     Germany
032     http://www.geographie.uni-bonn.de/deegree/
033    
034     e-mail: info@deegree.org
035    ----------------------------------------------------------------------------*/
036    
037    package org.deegree.ogcwebservices.wpvs.utils;
038    
039    import java.awt.Color;
040    import java.awt.Graphics;
041    import java.awt.Image;
042    import java.awt.image.BufferedImage;
043    import java.awt.image.FilteredImageSource;
044    import java.awt.image.ImageFilter;
045    import java.awt.image.ImageProducer;
046    import java.awt.image.RGBImageFilter;
047    
048    /**
049     * Little utility class responsible for filtering an image and making it
050     * transparent based on an array of colors considered to be transparent.
051     * Users of this class initalize an object with a non-null <code>Color</code> array
052     * that represents colors, which are supposed to be completely transparent.
053     * By calling <code>#filter( Image )</code>, the colors found in image are substituted
054     * by transparent pixels.
055     *
056     * @author <a href="mailto:taddei@lat-lon.de">Ugo Taddei</a>
057     * @author last edited by: $Author: mschneider $
058     *
059     * $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18 Jun 2009) $
060     */
061    public class ImageUtils {
062    
063    
064            private ImageFilter filter;
065    
066            /**
067             *      Creates a new <code>ImageUtil</code> object.
068             * @param transparentColors the colors that will be substituted by a completely
069             * transparent color ('0x00FFFFFF'). transparentColors cannot be null.
070             */
071            public ImageUtils( Color[] transparentColors ){
072    
073                    if ( transparentColors == null ){
074                            throw new NullPointerException( "transparentColors cannot be null!" );
075                    }
076    
077                    int[] intColors = new int[ transparentColors.length ];
078            for ( int j = 0; j < intColors.length; j++ ) {
079                intColors[j] = transparentColors[j].getRGB();
080            }
081                    filter = new ImageUtils.ColorsToTransparentFilter( intColors );
082    
083            }
084    
085            /**
086             * Creates a Imagefilter which makes an image transparent.
087             */
088            public ImageUtils( ){
089                    filter = new ImageUtils.TransparentImageFilter();
090    
091            }
092    
093            /**
094             * Filters an image and return a new partially transparent image.
095             * @param image the image that is to be filtered.
096             * @return a new image whose colors are substituted accordign to the
097             * input traparent colors. The input image cannot be null.
098             */
099            public Image filterImage( BufferedImage image ){
100    
101                    if ( image == null ){
102                            throw new NullPointerException( "Image cannot be null!" );
103                    }
104                    image = ensureRGBAImage( image );
105                    ImageProducer imgProducer =
106                new FilteredImageSource( image.getSource(), filter );
107    
108                    return java.awt.Toolkit.getDefaultToolkit().createImage( imgProducer );
109            }
110    
111            /**
112             * Checks if the type of <code>img</code> is <code>BufferedImage.TYPE_INT_ARGB</code>
113             * and if is not, create a new one, just like <code>img</code> but with transparency
114             * @param image the image to be checked. Cannot be null.
115             * @return the same image, if its type is <code>BufferedImage.TYPE_INT_ARGB</code>, or a
116             * new transparent one.
117             */
118            public BufferedImage ensureRGBAImage( BufferedImage image ) {
119    
120                    if ( image == null ){
121                            throw new NullPointerException( "Image cannot be null!" );
122                    }
123    
124                if ( image.getType() != BufferedImage.TYPE_INT_ARGB ) {
125                    BufferedImage tmp = new BufferedImage( image.getWidth(), image.getHeight(),
126                                                           BufferedImage.TYPE_INT_ARGB );
127                    Graphics g = tmp.getGraphics();
128                    g.drawImage( image, 0, 0, null );
129                    g.dispose();
130                    image = tmp;
131                }
132                return image;
133            }
134    
135            /**
136             * An <code>RGBImageFilter</code> to substitute all input colors by a completely
137             * transparent one.
138             *
139             * @author <a href="mailto:taddei@lat-lon.de">Ugo Taddei</a>
140             * @author last edited by: $Author: mschneider $
141             *
142             * $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18 Jun 2009) $
143             */
144            public class ColorsToTransparentFilter extends RGBImageFilter {
145    
146                    private static final int TRANSPARENT_COLOR = 0x00FFFFFF;
147    
148                    private final int[] colors;
149    
150                    /**
151                     * 0.975f
152                     */
153                    float alphaPercent = 0.975f;
154    
155                /**
156                 * @param colors the Colors which should be transparent
157                 */
158                public ColorsToTransparentFilter( int[] colors ) {
159                    if ( colors == null || colors.length == 0){
160                                    throw new NullPointerException( "colors cannot be null!" );
161                            }
162                    this.colors = colors;
163                    canFilterIndexColorModel = true;
164                }
165    
166                /**
167                 * @see java.awt.image.RGBImageFilter
168                 */
169                @Override
170            public int filterRGB(int x, int y, int argb) {
171                    if( shouldBeTransparent( argb ) ) {
172                       return TRANSPARENT_COLOR; // mask alpha bits to zero
173    //                      argb = TRANSPARENT_COLOR;
174                    }
175                    return argb;
176                    /*int a = ( argb >> 24) & 0xff;
177                    a *= alphaPercent;
178                    return ( ( argb & 0x00ffffff) | (a << 24));*/
179                }
180    
181                /**
182                 * Compares <code>color</code> with TRANSPARENT_COLOR
183                 * @param color color to be compared to TRANSPARENT_COLOR
184                 * @return true if color = TRANSPARENT_COLOR
185                 */
186                private boolean shouldBeTransparent( int color ) {
187                    for ( int i = 0; i < colors.length; i++ ) {
188                        if ( colors[i] == color ) {
189                            return true;
190                        }
191                    }
192                    return false;
193                }
194            }
195    
196            /* from Java AWT reference, chap. 12*/
197            /**
198             * The <code>TransparentImageFilter</code> class filters an RGB-Pixel with a transparency.
199             *
200         * @author <a href="mailto:taddei@lat-lon.de">Ugo Taddei</a>
201             *
202             * @author last edited by: $Author: mschneider $
203             *
204             * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18 Jun 2009) $
205             *
206             */
207            class TransparentImageFilter extends RGBImageFilter {
208                /**
209                 * the alpha chanel.
210                 */
211                float alphaPercent;
212                /**
213                 * A TransparentImageFilter with no transparency
214                 */
215                public TransparentImageFilter () {
216                    this (1f);
217                }
218                /**
219                 * @param aPercent of the transparency
220                 */
221                public TransparentImageFilter (float aPercent) {
222                    if ((aPercent < 0.0) || (aPercent > 1.0))
223                        aPercent = 1;
224                    alphaPercent = aPercent;
225                    canFilterIndexColorModel = true;
226                }
227                @Override
228            public int filterRGB (int x, int y, int rgb) {
229                    int a = (rgb >> 24) & 0xff;
230                    a *= alphaPercent;
231    
232                    return ((rgb & 0x00ffffff) | (a << 24));
233                }
234            }
235    }
236