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 }