001    // $HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/framework/util/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    package org.deegree.framework.util;
037    
038    import static org.deegree.enterprise.WebUtils.enableProxyUsage;
039    
040    import java.awt.image.BufferedImage;
041    import java.io.File;
042    import java.io.FileOutputStream;
043    import java.io.IOException;
044    import java.io.InputStream;
045    import java.io.OutputStream;
046    import java.net.URL;
047    
048    import javax.imageio.ImageIO;
049    import javax.media.jai.JAI;
050    import javax.media.jai.PlanarImage;
051    import javax.media.jai.RenderedOp;
052    
053    import org.apache.batik.ext.awt.image.codec.ImageDecoderImpl;
054    import org.apache.batik.ext.awt.image.codec.PNGDecodeParam;
055    import org.apache.batik.ext.awt.image.codec.PNGImageDecoder;
056    import org.apache.batik.ext.awt.image.codec.tiff.TIFFDecodeParam;
057    import org.apache.batik.ext.awt.image.codec.tiff.TIFFImage;
058    import org.apache.commons.httpclient.HttpClient;
059    import org.apache.commons.httpclient.methods.GetMethod;
060    
061    import Acme.JPM.Encoders.GifEncoder;
062    
063    import com.sun.image.codec.jpeg.JPEGCodec;
064    import com.sun.image.codec.jpeg.JPEGImageEncoder;
065    import com.sun.media.jai.codec.BMPEncodeParam;
066    import com.sun.media.jai.codec.ImageCodec;
067    import com.sun.media.jai.codec.MemoryCacheSeekableStream;
068    import com.sun.media.jai.codec.PNGEncodeParam;
069    import com.sun.media.jai.codec.SeekableStream;
070    import com.sun.media.jai.codec.TIFFEncodeParam;
071    
072    /**
073     * Some utility methods for reading standard images
074     *
075     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
076     * @author last edited by: $Author: mschneider $
077     *
078     * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
079     */
080    public class ImageUtils {
081    
082        /**
083         * reads an image from the passed <tt>URL</tt> using JAI mechanism
084         *
085         * @param url
086         *            address of the image
087         *
088         * @return read image
089         *
090         * @throws IOException
091         */
092        public static BufferedImage loadImage( URL url )
093                                throws IOException {
094            if ( url.toExternalForm().startsWith( "file" ) ) {
095                return loadImage( url.openStream() );
096            }
097    
098            String uri = url.toExternalForm();
099            HttpClient httpclient = new HttpClient();
100            enableProxyUsage( httpclient, url );
101            httpclient.getHttpConnectionManager().getParams().setSoTimeout( 25000 );
102            GetMethod httpget = new GetMethod( uri );
103            httpclient.executeMethod( httpget );
104            return loadImage( httpget.getResponseBodyAsStream() );
105    
106        }
107    
108        /**
109         * reads an image from the passed <tt>InputStream</tt> using JAI mechanism
110         *
111         * @param is
112         *
113         * @return read image
114         *
115         * @throws IOException
116         */
117        public static BufferedImage loadImage( InputStream is )
118                                throws IOException {
119            SeekableStream fss = new MemoryCacheSeekableStream( is );
120            RenderedOp ro = JAI.create( "stream", fss );
121            BufferedImage img = ro.getAsBufferedImage();
122            fss.close();
123            is.close();
124            return img;
125        }
126    
127        /**
128         * reads an image from the passed file location using JAI mechanism
129         *
130         * @param fileName
131         *
132         * @return read imagey
133         *
134         * @throws IOException
135         */
136        public static BufferedImage loadImage( String fileName )
137                                throws IOException {
138            return loadImage( new File( fileName ) );
139        }
140    
141        /**
142         * reads an image from the passed file location using JAI mechanism
143         *
144         * @param file
145         *
146         * @return read image
147         *
148         * @throws IOException
149         */
150        public static BufferedImage loadImage( File file )
151                                throws IOException {
152    
153            BufferedImage img = null;
154            String tmp = file.getName().toLowerCase();
155            if ( tmp.endsWith( ".tif" ) || tmp.endsWith( ".tiff" ) ) {
156                InputStream is = file.toURL().openStream();
157                org.apache.batik.ext.awt.image.codec.SeekableStream fss = new org.apache.batik.ext.awt.image.codec.MemoryCacheSeekableStream(
158                                                                                                                                              is );
159                TIFFImage tiff = new TIFFImage( fss, new TIFFDecodeParam(), 0 );
160                img = PlanarImage.wrapRenderedImage( tiff ).getAsBufferedImage();
161                fss.close();
162            } else if ( tmp.endsWith( ".png" ) ) {
163                InputStream is = file.toURL().openStream();
164                ImageDecoderImpl dec = new PNGImageDecoder( is, new PNGDecodeParam() );
165                img = PlanarImage.wrapRenderedImage( dec.decodeAsRenderedImage() ).getAsBufferedImage();
166                is.close();
167            } else {
168                img = ImageIO.read( file );
169            }
170    
171            return img;
172        }
173    
174        /**
175         * stores the passed image in the passed file name with defined quality
176         *
177         * @param image
178         * @param fileName
179         * @param quality
180         *            just supported for jpeg (0..1)
181         * @throws IOException
182         */
183        public static void saveImage( BufferedImage image, String fileName, float quality )
184                                throws IOException {
185            File file = new File( fileName );
186            saveImage( image, file, quality );
187        }
188    
189        /**
190         * stores the passed image in the passed file with defined quality
191         *
192         * @param image
193         * @param file
194         * @param quality
195         *            just supported for jpeg (0..1)
196         * @throws IOException
197         */
198        public static void saveImage( BufferedImage image, File file, float quality )
199                                throws IOException {
200            int pos = file.getName().lastIndexOf( '.' );
201            String ext = file.getName().substring( pos + 1, file.getName().length() ).toLowerCase();
202    
203            FileOutputStream fos = new FileOutputStream( file );
204            saveImage( image, fos, ext, quality );
205    
206        }
207    
208        /**
209         * write an image into the passed output stream. after writing the image the stream will be closed.
210         *
211         * @param image
212         * @param os
213         * @param format
214         * @param quality
215         * @throws IOException
216         */
217        public static void saveImage( BufferedImage image, OutputStream os, String format, float quality )
218                                throws IOException {
219            try {
220    
221                if ( "jpeg".equalsIgnoreCase( format ) || "jpg".equalsIgnoreCase( format ) ) {
222                    encodeJpeg( os, image, quality );
223                } else if ( "tif".equalsIgnoreCase( format ) || "tiff".equalsIgnoreCase( format ) ) {
224                    encodeTiff( os, image );
225                } else if ( "png".equalsIgnoreCase( format ) ) {
226                    encodePng( os, image );
227                } else if ( "gif".equalsIgnoreCase( format ) ) {
228                    encodeGif( os, image );
229                } else if ( "bmp".equalsIgnoreCase( format ) ) {
230                    encodeBmp( os, image );
231                } else {
232                    throw new IOException( "invalid image format: " + format );
233                }
234            } catch ( IOException e ) {
235                throw e;
236            } finally {
237                os.flush();
238                os.close();
239            }
240    
241        }
242    
243        /**
244         *
245         *
246         * @param out
247         * @param img
248         *
249         * @throws IOException
250         */
251        public static void encodeGif( OutputStream out, BufferedImage img )
252                                throws IOException {
253            GifEncoder encoder = new GifEncoder( img, out );
254            encoder.encode();
255        }
256    
257        /**
258         *
259         *
260         * @param out
261         * @param img
262         *
263         * @throws IOException
264         */
265        private static void encodeBmp( OutputStream out, BufferedImage img )
266                                throws IOException {
267            BMPEncodeParam encodeParam = new BMPEncodeParam();
268    
269            com.sun.media.jai.codec.ImageEncoder encoder = ImageCodec.createImageEncoder( "BMP", out, encodeParam );
270    
271            encoder.encode( img );
272        }
273    
274        /**
275         *
276         *
277         * @param out
278         * @param img
279         *
280         * @throws IOException
281         */
282        private static void encodePng( OutputStream out, BufferedImage img )
283                                throws IOException {
284            PNGEncodeParam encodeParam = PNGEncodeParam.getDefaultEncodeParam( img );
285    
286            if ( encodeParam instanceof PNGEncodeParam.Palette ) {
287                PNGEncodeParam.Palette p = (PNGEncodeParam.Palette) encodeParam;
288                byte[] b = new byte[] { -127 };
289                p.setPaletteTransparency( b );
290            }
291    
292            com.sun.media.jai.codec.ImageEncoder encoder = ImageCodec.createImageEncoder( "PNG", out, encodeParam );
293            encoder.encode( img.getData(), img.getColorModel() );
294        }
295    
296        /**
297         *
298         *
299         * @param out
300         * @param img
301         *
302         * @throws IOException
303         */
304        private static void encodeTiff( OutputStream out, BufferedImage img )
305                                throws IOException {
306            TIFFEncodeParam encodeParam = new TIFFEncodeParam();
307    
308            com.sun.media.jai.codec.ImageEncoder encoder = ImageCodec.createImageEncoder( "TIFF", out, encodeParam );
309    
310            encoder.encode( img );
311        }
312    
313        /**
314         *
315         *
316         * @param out
317         * @param img
318         * @param quality
319         *
320         * @throws IOException
321         */
322        private static void encodeJpeg( OutputStream out, BufferedImage img, float quality )
323                                throws IOException {
324    
325            // encode JPEG
326            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder( out );
327            com.sun.image.codec.jpeg.JPEGEncodeParam jpegParams = encoder.getDefaultJPEGEncodeParam( img );
328            jpegParams.setQuality( quality, false );
329            encoder.setJPEGEncodeParam( jpegParams );
330    
331            encoder.encode( img );
332        }
333    
334    }