001         package com.croftsoft.core.awt.image;
002    
003         import java.applet.*;
004         import java.awt.*;
005         import java.awt.image.*;
006         import java.io.*;
007         import javax.imageio.ImageIO;
008    
009         import com.croftsoft.core.lang.NullArgumentException;
010    
011         /*********************************************************************
012         * Static method library for manipulating Image objects.
013         *
014         * @version
015         *   $Id: ImageLib.java,v 1.2 2006/12/10 03:46:31 croft Exp $
016         * @since
017         *   1997-02-14
018         * @author
019         *   <a href="https://www.croftsoft.com/">David Wallace Croft</a>
020         *********************************************************************/
021    
022         public final class  ImageLib
023         //////////////////////////////////////////////////////////////////////
024         //////////////////////////////////////////////////////////////////////
025         {
026    
027         public static Image  crop (
028           Image   image,
029           int     x,
030           int     y,
031           int     w,
032           int     h,
033           Applet  applet )
034         //////////////////////////////////////////////////////////////////////
035         // p274, Java in a Nutshell, 1st Edition
036         //////////////////////////////////////////////////////////////////////
037         {
038           ImageFilter  cropper = new CropImageFilter ( x, y, w, h );
039    
040           ImageProducer  prod
041             = new FilteredImageSource ( image.getSource ( ), cropper );
042    
043           if ( applet != null )
044           {
045             return applet.createImage ( prod );
046           }
047           else
048           {
049             return Toolkit.getDefaultToolkit ( ).createImage ( prod );
050           }
051         }
052    
053         /*********************************************************************
054         * Loads an automatic image from a resource file.
055         *
056         * @param  imageFilename
057         *
058         *    The path/filename of the resource image, usually within a JAR.
059         *
060         * @param  transparency
061         *
062         *    Transparency.BITMASK, .OPAQUE, or .TRANSLUCENT.
063         *
064         * @param  component
065         *
066         *    The image will be compatible with this Component.
067         *
068         * @param  classLoader
069         *
070         *    If null, component.getClass ( ).getClassLoader ( ) is used.
071         *
072         * @param  dimension
073         *
074         *    If null, the image will not be scaled.
075         *********************************************************************/
076         public static BufferedImage  loadAutomaticImage (
077           String       imageFilename,
078           int          transparency,
079           Component    component,
080           ClassLoader  classLoader,
081           Dimension    dimension )
082           throws IOException
083         //////////////////////////////////////////////////////////////////////
084         {
085           NullArgumentException.check ( imageFilename );
086    
087           NullArgumentException.check ( component );
088    
089           if ( classLoader == null )
090           {
091             classLoader = component.getClass ( ).getClassLoader ( );
092           }
093    
094           BufferedImage  bufferedImage
095             = loadBufferedImage ( imageFilename, classLoader );
096    
097           GraphicsConfiguration  graphicsConfiguration
098             = component.getGraphicsConfiguration ( );
099    
100           if ( graphicsConfiguration == null )
101           {
102             throw new IllegalStateException ( "null graphicsConfiguration" );
103           }
104    
105           int  width, height;
106    
107           if ( dimension == null )
108           {
109             width  = bufferedImage.getWidth  ( );
110    
111             height = bufferedImage.getHeight ( );
112           }
113           else
114           {
115             width  = dimension.width;
116    
117             height = dimension.height;
118    
119             if ( width < 1 )
120             {
121               throw new IllegalArgumentException (
122                 "dimension.width < 1:  " + width );
123             }
124    
125             if ( height < 1 )
126             {
127               throw new IllegalArgumentException (
128                 "dimension.height < 1:  " + height );
129             }
130           }
131    
132           BufferedImage  automaticImage
133             = graphicsConfiguration.createCompatibleImage (
134             width, height, transparency );
135    
136           Graphics  graphics = automaticImage.getGraphics ( );
137    
138           if ( dimension == null )
139           {
140             graphics.drawImage ( bufferedImage, 0, 0, null );
141           }
142           else
143           {
144             graphics.drawImage ( bufferedImage, 0, 0, width, height, null );
145           }
146    
147           graphics.dispose ( );
148    
149           bufferedImage.flush ( );
150    
151           return automaticImage;
152         }
153    
154         public static BufferedImage  loadBufferedImage (
155           String       imageFilename,
156           ClassLoader  classLoader )
157           throws IOException
158         //////////////////////////////////////////////////////////////////////
159         {
160           // ImageIO.read(URL) seems to be buggy when running within an applet
161           // on Linux/Netscape so ImageIO.read(InputStream) is used instead.
162           // The problem may be that the InputStream is not flushed or closed.
163            
164           InputStream  inputStream
165             = classLoader.getResourceAsStream ( imageFilename );
166    
167           if ( inputStream == null )
168           {
169             return null;
170           }
171    
172           BufferedInputStream  bufferedInputStream
173             = new BufferedInputStream ( inputStream );
174    
175           BufferedImage  bufferedImage = ImageIO.read ( bufferedInputStream );
176    
177           bufferedInputStream.close ( );
178    
179           return bufferedImage;
180         }
181         
182         public static Dimension  shrinkToFit (
183           final int  imageWidth,
184           final int  imageHeight,
185           final int  graphicsWidth,
186           final int  graphicsHeight )
187         //////////////////////////////////////////////////////////////////////
188         {
189           if ( ( imageWidth     < 1 )
190             || ( imageHeight    < 1 )
191             || ( graphicsWidth  < 1 )
192             || ( graphicsHeight < 1 ) )
193           {
194             throw new IllegalArgumentException ( "value < 1" );
195           }
196           
197           if ( ( imageWidth  <= graphicsWidth  )
198             && ( imageHeight <= graphicsHeight ) )
199           {
200             return new Dimension ( imageWidth, imageHeight );
201           }
202           
203           final double  widthRatio
204             = ( ( double ) imageWidth  ) / graphicsWidth;
205           
206           final double  heightRatio
207             = ( ( double ) imageHeight ) / graphicsHeight;
208           
209           if ( widthRatio > heightRatio )
210           {
211             return new Dimension (
212               graphicsWidth, ( int ) ( imageHeight / widthRatio ) );
213           }
214    
215           return new Dimension (
216             ( int ) ( imageWidth / heightRatio ), graphicsHeight );
217         }
218    
219         public static Rectangle  shrinkToFitAndCenter (
220           final int  imageWidth,
221           final int  imageHeight,
222           final int  graphicsWidth,
223           final int  graphicsHeight )
224         //////////////////////////////////////////////////////////////////////
225         {
226           final Dimension  dimension = shrinkToFit (
227             imageWidth, imageHeight, graphicsWidth, graphicsHeight );
228           
229           final int  deltaWidth  = graphicsWidth  - dimension.width;
230           
231           final int  deltaHeight = graphicsHeight - dimension.height;
232           
233           return new Rectangle (
234             deltaWidth  / 2,
235             deltaHeight / 2,
236             dimension.width,
237             dimension.height );
238         }
239         
240         //////////////////////////////////////////////////////////////////////
241         //////////////////////////////////////////////////////////////////////
242    
243         private  ImageLib ( ) { /* empty */ }
244    
245         //////////////////////////////////////////////////////////////////////
246         //////////////////////////////////////////////////////////////////////
247         }