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 }