The image manager now falls back to loading images via the Toolkit if it
can't load the ImageIO classes. This unfortunately means that we're back to passing a Component instance to the ImageManager at construct time. Whee! git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@749 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// $Id: ImageIOLoader.java,v 1.1 2001/12/07 01:33:29 mdb Exp $
|
||||
|
||||
package com.threerings.media;
|
||||
|
||||
import java.awt.Image;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
/**
|
||||
* Loads images using the <code>ImageIO</code> services provided by J2SE
|
||||
* 1.4 (and, presumably, above).
|
||||
*/
|
||||
public class ImageIOLoader
|
||||
{
|
||||
// documentation inherited
|
||||
public Image loadImage (InputStream source)
|
||||
throws IOException
|
||||
{
|
||||
// this seems to choke when decoding the compressed image data
|
||||
// which may mean it's a JDK bug or something, but I'd like to see
|
||||
// it resolved so that the image manager will work on applets
|
||||
//
|
||||
// ImageInputStream iis = new MemoryCacheImageInputStream(source);
|
||||
// return ImageIO.read(iis);
|
||||
|
||||
return ImageIO.read(source);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// $Id: ImageLoader.java,v 1.1 2001/12/07 01:33:29 mdb Exp $
|
||||
|
||||
package com.threerings.media;
|
||||
|
||||
import java.awt.Image;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* In order to take advantage of the new J2SE 1.4 image loading facilites
|
||||
* (in the form of <code>ImageIO</code> and friends), while preserving the
|
||||
* ability to operate on J2SE 1.3 and previous, we have the image loader
|
||||
* interface. It allows us to attempt to load the ImageIO based loader and
|
||||
* fall back if the class is not available.
|
||||
*/
|
||||
public interface ImageLoader
|
||||
{
|
||||
/**
|
||||
* Load up the image from the supplied input stream.
|
||||
*/
|
||||
public Image loadImage (InputStream source)
|
||||
throws IOException;
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
//
|
||||
// $Id: ImageManager.java,v 1.8 2001/11/30 02:33:34 mdb Exp $
|
||||
// $Id: ImageManager.java,v 1.9 2001/12/07 01:33:29 mdb Exp $
|
||||
|
||||
package com.threerings.media;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Image;
|
||||
import java.awt.Transparency;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
@@ -17,7 +19,6 @@ import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageReader;
|
||||
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
@@ -33,9 +34,13 @@ public class ImageManager
|
||||
{
|
||||
/**
|
||||
* Construct an image manager with the specified {@link
|
||||
* ResourceManager} from which it will obtain its data.
|
||||
* ResourceManager} from which it will obtain its data. A non-null
|
||||
* <code>context</code> must be provided if there is any expectation
|
||||
* that the image manager will not be able to load images via the
|
||||
* ImageIO services and will have to fallback to Toolkit-style
|
||||
* loading.
|
||||
*/
|
||||
public ImageManager (ResourceManager rmgr)
|
||||
public ImageManager (ResourceManager rmgr, Component context)
|
||||
{
|
||||
_rmgr = rmgr;
|
||||
|
||||
@@ -44,16 +49,25 @@ public class ImageManager
|
||||
GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
GraphicsDevice gdev = genv.getDefaultScreenDevice();
|
||||
_gconf = gdev.getDefaultConfiguration();
|
||||
|
||||
// try to figure out which image loader we'll be using
|
||||
try {
|
||||
_loader = (ImageLoader)Class.forName(IMAGEIO_LOADER).newInstance();
|
||||
} catch (Exception e) {
|
||||
Log.info("Unable to use ImageIO to load images. " +
|
||||
"Falling back to Toolkit.");
|
||||
_loader = new ToolkitLoader(context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the image via the resource manager using the specified path
|
||||
* and caches it for faster retrieval henceforth.
|
||||
*/
|
||||
public BufferedImage getImage (String path)
|
||||
public Image getImage (String path)
|
||||
throws IOException
|
||||
{
|
||||
BufferedImage img = (BufferedImage)_imgs.get(path);
|
||||
Image img = (Image)_imgs.get(path);
|
||||
if (img != null) {
|
||||
// Log.info("Retrieved image from cache [path=" + path + "].");
|
||||
return img;
|
||||
@@ -70,19 +84,12 @@ public class ImageManager
|
||||
* environment and decodes the image data from the specified source
|
||||
* image into that target image. The resulting image is not cached.
|
||||
*/
|
||||
public BufferedImage createImage (InputStream source)
|
||||
public Image createImage (InputStream source)
|
||||
throws IOException
|
||||
{
|
||||
// this seems to choke when decoding the compressed image data
|
||||
// which may mean it's a JDK bug or something, but I'd like to see
|
||||
// it resolved so that the image manager will work on applets
|
||||
//
|
||||
// ImageInputStream iis = new MemoryCacheImageInputStream(source);
|
||||
// BufferedImage src = ImageIO.read(iis);
|
||||
|
||||
BufferedImage src = ImageIO.read(source);
|
||||
int swidth = src.getWidth();
|
||||
int sheight = src.getHeight();
|
||||
Image src = _loader.loadImage(source);
|
||||
int swidth = src.getWidth(null);
|
||||
int sheight = src.getHeight(null);
|
||||
|
||||
// now convert the image to a format optimized for display
|
||||
BufferedImage dest = _gconf.createCompatibleImage(
|
||||
@@ -98,9 +105,19 @@ public class ImageManager
|
||||
* by default. */
|
||||
protected ResourceManager _rmgr;
|
||||
|
||||
/** The image loader via which we convert an input stream into an
|
||||
* image. */
|
||||
protected ImageLoader _loader;
|
||||
|
||||
/** A cache of loaded images. */
|
||||
protected HashMap _imgs = new HashMap();
|
||||
|
||||
/** The graphics configuration of our default display device. */
|
||||
protected GraphicsConfiguration _gconf;
|
||||
|
||||
/** The classname of the ImageIO-based image loader which we attempt
|
||||
* to use but fallback from if we're not running a JVM that has
|
||||
* ImageIO support. */
|
||||
protected static final String IMAGEIO_LOADER =
|
||||
"com.threerings.media.ImageIOLoader";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// $Id: ImageUtil.java,v 1.1 2001/12/07 01:33:29 mdb Exp $
|
||||
|
||||
package com.threerings.media;
|
||||
|
||||
import java.awt.Image;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
/**
|
||||
* Image related utility functions.
|
||||
*/
|
||||
public class ImageUtil
|
||||
{
|
||||
/**
|
||||
* Extracts a subimage from the supplied image with the specified
|
||||
* dimensions. If the supplied image is an instance of {@link
|
||||
* BufferedImage}, then the subimage will simply reference the main
|
||||
* image. If it is not, the subimage will be created and the data will
|
||||
* be rendered into the newly created image.
|
||||
*
|
||||
* @return the desired subimage.
|
||||
*/
|
||||
public static Image getSubimage (
|
||||
Image source, int x, int y, int width, int height)
|
||||
{
|
||||
if (source instanceof BufferedImage) {
|
||||
return ((BufferedImage)source).getSubimage(x, y, width, height);
|
||||
|
||||
} else {
|
||||
BufferedImage target =
|
||||
new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics g = target.getGraphics();
|
||||
g.drawImage(source, 0, 0, width, height,
|
||||
x, y, x+width, y+height, null);
|
||||
g.dispose();
|
||||
return target;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
//
|
||||
// $Id: ToolkitLoader.java,v 1.1 2001/12/07 01:33:29 mdb Exp $
|
||||
|
||||
package com.threerings.media;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Image;
|
||||
import java.awt.MediaTracker;
|
||||
import java.awt.Toolkit;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.commons.util.StreamUtils;
|
||||
|
||||
/**
|
||||
* Loads images using the default AWT toolkit (for compatibility with
|
||||
* pre-1.4 JVMs).
|
||||
*/
|
||||
public class ToolkitLoader implements ImageLoader
|
||||
{
|
||||
public ToolkitLoader (Component context)
|
||||
{
|
||||
// do something more informative than NPE if we're misconfigured
|
||||
if (context == null) {
|
||||
String errmsg = "Toolkit image loader constructed without a " +
|
||||
"context via which we can create a MediaTracker. If the " +
|
||||
"image manager may fall back to using the Toolkit image " +
|
||||
"loader (like it just did), then you have to provide a " +
|
||||
"component instance for it at construct time. Thanks and " +
|
||||
"have a nice day.";
|
||||
throw new RuntimeException(errmsg);
|
||||
}
|
||||
|
||||
_toolkit = context.getToolkit();
|
||||
_tracker = new MediaTracker(context);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public Image loadImage (InputStream source)
|
||||
throws IOException
|
||||
{
|
||||
byte[] data = StreamUtils.streamAsBytes(source, READ_BUFFER_SIZE);
|
||||
Image image = _toolkit.createImage(data);
|
||||
|
||||
// we now have to wait for the image to finish decoding (this all
|
||||
// apparently happens on another thread. yay!)
|
||||
_tracker.addImage(image, 0);
|
||||
|
||||
// if something goes horribly awry, we don't want to go into an
|
||||
// infinite loop, so we bound the number of times we'll allow
|
||||
// ourselves to be interrupted and loop
|
||||
boolean done = false;
|
||||
for (int i = 0; (i < 1000) && !done; i++) {
|
||||
try {
|
||||
_tracker.waitForAll();
|
||||
done = true;
|
||||
} catch (InterruptedException e) {
|
||||
// loop back around
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
/** Our AWT toolkit which we use to create images. */
|
||||
protected Toolkit _toolkit;
|
||||
|
||||
/** Used to wait for images to load. */
|
||||
protected MediaTracker _tracker;
|
||||
|
||||
/** The size of the read buffer used to load the image data. */
|
||||
protected static final int READ_BUFFER_SIZE = 4096;
|
||||
}
|
||||
Reference in New Issue
Block a user