001    // $HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/framework/util/ImageUtils.java $
002    /*----------------    FILE HEADER  ------------------------------------------
003    
004     This file is part of deegree.
005     Copyright (C) 2001-2008 by:
006     EXSE, Department of Geography, University of Bonn
007     http://www.giub.uni-bonn.de/deegree/
008     lat/lon GmbH
009     http://www.lat-lon.de
010    
011     This library is free software; you can redistribute it and/or
012     modify it under the terms of the GNU Lesser General Public
013     License as published by the Free Software Foundation; either
014     version 2.1 of the License, or (at your option) any later version.
015    
016     This library is distributed in the hope that it will be useful,
017     but WITHOUT ANY WARRANTY; without even the implied warranty of
018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
019     Lesser General Public License for more details.
020    
021     You should have received a copy of the GNU Lesser General Public
022     License along with this library; if not, write to the Free Software
023     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
024    
025     Contact:
026    
027     Andreas Poth
028     lat/lon GmbH
029     Aennchenstr. 19
030     53115 Bonn
031     Germany
032     E-Mail: poth@lat-lon.de
033    
034     Prof. Dr. Klaus Greve
035     Department of Geography
036     University of Bonn
037     Meckenheimer Allee 166
038     53115 Bonn
039     Germany
040     E-Mail: greve@giub.uni-bonn.de
041    
042     
043     ---------------------------------------------------------------------------*/
044    package org.deegree.framework.util;
045    
046    import static org.deegree.enterprise.WebUtils.enableProxyUsage;
047    
048    import java.awt.image.BufferedImage;
049    import java.io.File;
050    import java.io.FileOutputStream;
051    import java.io.IOException;
052    import java.io.InputStream;
053    import java.io.OutputStream;
054    import java.net.URL;
055    
056    import javax.imageio.ImageIO;
057    import javax.media.jai.JAI;
058    import javax.media.jai.RenderedOp;
059    
060    import org.apache.batik.ext.awt.image.codec.ImageDecoderImpl;
061    import org.apache.batik.ext.awt.image.codec.PNGDecodeParam;
062    import org.apache.batik.ext.awt.image.codec.PNGImageDecoder;
063    import org.apache.batik.ext.awt.image.codec.tiff.TIFFDecodeParam;
064    import org.apache.batik.ext.awt.image.codec.tiff.TIFFImage;
065    import org.apache.commons.httpclient.HttpClient;
066    import org.apache.commons.httpclient.methods.GetMethod;
067    
068    import Acme.JPM.Encoders.GifEncoder;
069    
070    import com.sun.image.codec.jpeg.JPEGCodec;
071    import com.sun.image.codec.jpeg.JPEGImageEncoder;
072    import com.sun.media.jai.codec.BMPEncodeParam;
073    import com.sun.media.jai.codec.ImageCodec;
074    import com.sun.media.jai.codec.MemoryCacheSeekableStream;
075    import com.sun.media.jai.codec.PNGEncodeParam;
076    import com.sun.media.jai.codec.SeekableStream;
077    import com.sun.media.jai.codec.TIFFEncodeParam;
078    
079    /**
080     * Some util methods for reading standard images
081     * 
082     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
083     * @author last edited by: $Author: aschmitz $
084     * 
085     * @version $Revision: 12685 $, $Date: 2008-07-07 10:01:54 +0200 (Mo, 07 Jul 2008) $
086     */
087    public class ImageUtils {
088    
089        /**
090         * reads an image from the passed <tt>URL</tt> using JAI mechanism
091         * 
092         * @param url
093         *            address of the image
094         * 
095         * @return read image
096         * 
097         * @throws IOException
098         */
099        public static BufferedImage loadImage( URL url )
100                                throws IOException {
101            if ( url.toExternalForm().startsWith( "file" ) ) {
102                return loadImage( url.openStream() );
103            }
104    
105            String uri = url.toExternalForm();
106            HttpClient httpclient = new HttpClient();
107            enableProxyUsage( httpclient, url );
108            httpclient.getHttpConnectionManager().getParams().setSoTimeout( 25000 );
109            GetMethod httpget = new GetMethod( uri );
110            httpclient.executeMethod( httpget );
111            return loadImage( httpget.getResponseBodyAsStream() );
112    
113        }
114    
115        // TODO check url-@param Tag
116        /**
117         * reads an image from the passed <tt>InputStream</tt> using JAI mechanism
118         * 
119         * @param is
120         * @param url
121         *            address of the image
122         * 
123         * @return read image
124         * 
125         * @throws IOException
126         */
127        public static BufferedImage loadImage( InputStream is )
128                                throws IOException {
129            SeekableStream fss = new MemoryCacheSeekableStream( is );
130            RenderedOp ro = JAI.create( "stream", fss );
131            BufferedImage img = ro.getAsBufferedImage();
132            fss.close();
133            is.close();
134            return img;
135        }
136    
137        /**
138         * reads an image from the passed file location using JAI mechanism
139         * 
140         * @param fileName
141         * 
142         * @return read imagey
143         * 
144         * @throws IOException
145         */
146        public static BufferedImage loadImage( String fileName )
147                                throws IOException {
148            return loadImage( new File( fileName ) );
149        }
150    
151        /**
152         * reads an image from the passed file location using JAI mechanism
153         * 
154         * @param file
155         * 
156         * @return read imagey
157         * 
158         * @throws IOException
159         */
160        public static BufferedImage loadImage( File file )
161                                throws IOException {
162    
163            BufferedImage img = null;
164            String tmp = file.getName().toLowerCase();
165            if ( tmp.endsWith( ".tif" ) || tmp.endsWith( ".tiff" ) ) {
166                InputStream is = file.toURL().openStream();
167                org.apache.batik.ext.awt.image.codec.SeekableStream fss = new org.apache.batik.ext.awt.image.codec.MemoryCacheSeekableStream(
168                                                                                                                                              is );
169                TIFFImage tiff = new TIFFImage( fss, new TIFFDecodeParam(), 0 );
170                img = RenderedOp.wrapRenderedImage( tiff ).getAsBufferedImage();
171                fss.close();
172            } else if ( tmp.endsWith( ".png" ) ) {
173                InputStream is = file.toURL().openStream();
174                ImageDecoderImpl dec = new PNGImageDecoder( is, new PNGDecodeParam() );
175                img = RenderedOp.wrapRenderedImage( dec.decodeAsRenderedImage() ).getAsBufferedImage();
176                is.close();
177            } else {
178                img = ImageIO.read( file );
179            }
180    
181            return img;
182        }
183    
184        /**
185         * stores the passed image in the passed file name with defined quality
186         * 
187         * @param image
188         * @param fileName
189         * @param quality
190         *            just supported for jpeg (0..1)
191         * @throws IOException
192         */
193        public static void saveImage( BufferedImage image, String fileName, float quality )
194                                throws IOException {
195            File file = new File( fileName );
196            saveImage( image, file, quality );
197        }
198    
199        /**
200         * stores the passed image in the passed file with defined quality
201         * 
202         * @param image
203         * @param file
204         * @param quality
205         *            just supported for jpeg (0..1)
206         * @throws IOException
207         */
208        public static void saveImage( BufferedImage image, File file, float quality )
209                                throws IOException {
210            int pos = file.getName().lastIndexOf( '.' );
211            String ext = file.getName().substring( pos + 1, file.getName().length() ).toLowerCase();
212    
213            FileOutputStream fos = new FileOutputStream( file );
214            saveImage( image, fos, ext, quality );
215    
216        }
217    
218        /**
219         * write an image into the passed output stream. after writing the image the stream will be closed.
220         * 
221         * @param image
222         * @param os
223         * @param format
224         * @param quality
225         * @throws IOException
226         */
227        public static void saveImage( BufferedImage image, OutputStream os, String format, float quality )
228                                throws IOException {
229            try {
230    
231                if ( "jpeg".equalsIgnoreCase( format ) || "jpg".equalsIgnoreCase( format ) ) {
232                    encodeJpeg( os, image, quality );
233                } else if ( "tif".equalsIgnoreCase( format ) || "tiff".equalsIgnoreCase( format ) ) {
234                    encodeTiff( os, image );
235                } else if ( "png".equalsIgnoreCase( format ) ) {
236                    encodePng( os, image );
237                } else if ( "gif".equalsIgnoreCase( format ) ) {
238                    encodeGif( os, image );
239                } else if ( "bmp".equalsIgnoreCase( format ) ) {
240                    encodeBmp( os, image );
241                } else {
242                    throw new IOException( "invalid image format: " + format );
243                }
244            } catch ( IOException e ) {
245                throw e;
246            } finally {
247                os.close();
248            }
249    
250        }
251    
252        /**
253         * 
254         * 
255         * @param out
256         * @param img
257         * 
258         * @throws IOException
259         */
260        public static synchronized void encodeGif( OutputStream out, BufferedImage img )
261                                throws IOException {
262            GifEncoder encoder = new GifEncoder( img, out );
263            encoder.encode();
264        }
265    
266        /**
267         * 
268         * 
269         * @param out
270         * @param img
271         * 
272         * @throws IOException
273         */
274        private static synchronized void encodeBmp( OutputStream out, BufferedImage img )
275                                throws IOException {
276            BMPEncodeParam encodeParam = new BMPEncodeParam();
277    
278            com.sun.media.jai.codec.ImageEncoder encoder = ImageCodec.createImageEncoder( "BMP", out, encodeParam );
279    
280            encoder.encode( img );
281        }
282    
283        /**
284         * 
285         * 
286         * @param out
287         * @param img
288         * 
289         * @throws IOException
290         */
291        private static synchronized void encodePng( OutputStream out, BufferedImage img )
292                                throws IOException {
293            PNGEncodeParam encodeParam = PNGEncodeParam.getDefaultEncodeParam( img );
294    
295            if ( encodeParam instanceof PNGEncodeParam.Palette ) {
296                PNGEncodeParam.Palette p = (PNGEncodeParam.Palette) encodeParam;
297                byte[] b = new byte[] { -127 };
298                p.setPaletteTransparency( b );
299            }
300    
301            com.sun.media.jai.codec.ImageEncoder encoder = ImageCodec.createImageEncoder( "PNG", out, encodeParam );
302            encoder.encode( img.getData(), img.getColorModel() );
303        }
304    
305        /**
306         * 
307         * 
308         * @param out
309         * @param img
310         * 
311         * @throws IOException
312         */
313        private static synchronized void encodeTiff( OutputStream out, BufferedImage img )
314                                throws IOException {
315            TIFFEncodeParam encodeParam = new TIFFEncodeParam();
316    
317            com.sun.media.jai.codec.ImageEncoder encoder = ImageCodec.createImageEncoder( "TIFF", out, encodeParam );
318    
319            encoder.encode( img );
320        }
321    
322        /**
323         * 
324         * 
325         * @param out
326         * @param img
327         * @param quality
328         * 
329         * @throws IOException
330         */
331        private static synchronized void encodeJpeg( OutputStream out, BufferedImage img, float quality )
332                                throws IOException {
333    
334            // encode JPEG
335            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder( out );
336            com.sun.image.codec.jpeg.JPEGEncodeParam jpegParams = encoder.getDefaultJPEGEncodeParam( img );
337            jpegParams.setQuality( quality, false );
338            encoder.setJPEGEncodeParam( jpegParams );
339    
340            encoder.encode( img );
341        }
342    
343    }