/* * ImageFactory.java * Transform * * Copyright (c) 2009-2010 Flagstone Software Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of Flagstone Software Ltd. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ package com.flagstone.transform.util.image; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import java.net.URL; import java.net.URLConnection; import java.util.zip.DataFormatException; import com.flagstone.transform.image.ImageTag; /** * <p> * ImageFactory is used to generate an image definition object from an image * stored in a file, references by a URL or read from an stream. An plug-in * architecture allows decoders to be registered to handle different image * formats. The ImageFactory provides a standard interface for using the * decoders. * </p> * * <p> * Currently PNG, BMP and JPEG encoded images are supported by dedicated * decoders. The BufferedImageDecoder can be used to decode any format supported * using Java's ImageIO, including PNG, BMP and JPG format images. New decoders * can be added by implementing the ImageDecoder interface and registering them * in the ImageRegistry. * </p> * * <P> * The defineImage() methods return an Definition (the abstract base class for * all objects used to define shapes etc. in a Flash file. The exact class of * the object generated depends of the format of the image loaded. * </P> * * <table> * <tr> * <th>Class</th> * <th>Generated when...</th> * </tr> * * <tr> * <td valign="top">DefineJPEGImage2</td> * <td>A JPEG encoded image is loaded. The getFormat() method returns the class * constant JPEG.</td> * </tr> * * <tr> * <td valign="top">DefineImage</td> * <td>An indexed BMP or PNG image contains a colour table without transparent * colours or when a true colour image contains 16-bit or 24-bit colours is * loaded. The getFormat() method returns the class constants IDX8, RGB5 or * RGB8.</td> * </tr> * * <tr> * <td valign="top">DefineImage2</td> * <td>A BMP or PNG indexed image contains a colour table with transparent * colours is loaded or when a true colour image contains 32-bit bit colours. * The getFormat() method returns the class constants IDXA or RGBA.</td> * </tr> * * </table> * * <P> * Images are displayed in Flash by filling a shape with the image bitmap. The * defineEnclosingShape() method generates a rectangular shape object which * wraps the image: * * <pre> * int imageId = movie.newIdentifier(); * int shapeId = movie.newIdentifier(); * * Definition image = Image(defineImage(imageId, ...); * * int x = image.getWidth()/2; * int y = image.getHeight()/2; * * LineStyle style = new LineStyle(20, ColorTable.black()); * * movie.add(image); * movie.add(Image.defineEnclosingShape(shapeId, image, x, y, style); * </pre> * * <P> * Here the origin, used when placing the shape on the screen, is defined as the * centre of the shape. Other points may be defined to suit the alignment of the * shape when it is placed on the display list. * </P> */ public final class ImageFactory { /** The object used to decode the image. */ private transient ImageDecoder decoder; /** * Create an image definition for the image located in the specified file. * * @param file * a file containing the abstract path to the image. * * @throws IOException * if there is an error reading the file. * * @throws DataFormatException * if there is a problem decoding the image, either it is in an * unsupported format or an error occurred while decoding the * image data. */ public void read(final File file) throws IOException, DataFormatException { final ImageInfo info = new ImageInfo(); info.setInput(new RandomAccessFile(file, "r")); // info.setDetermineImageNumber(true); if (!info.check()) { throw new DataFormatException("Unsupported format"); } decoder = ImageRegistry.getImageProvider( info.getImageFormat().getMimeType()); decoder.read(new FileInputStream(file)); } /** * Create an image definition for the image referenced by a URL. * * @param url * the Uniform Resource Locator referencing the file. * * @throws IOException * if there is an error reading the file. * * @throws DataFormatException * if there is a problem decoding the image, either it is in an * unsupported format or an error occurred while decoding the * image data. */ public void read(final URL url) throws IOException, DataFormatException { final URLConnection connection = url.openConnection(); final int fileSize = connection.getContentLength(); if (fileSize < 0) { throw new FileNotFoundException(url.getFile()); } final String mimeType = connection.getContentType(); decoder = ImageRegistry.getImageProvider(mimeType); if (decoder == null) { throw new DataFormatException("Unsupported format"); } decoder.read(url.openStream()); } /** * Create an image definition for an image read from a stream. * * @param stream * the InputStream containing the image data. * * @throws IOException * if there is an error reading the stream. * * @throws DataFormatException * if there is a problem decoding the image, either it is in an * unsupported format or an error occurred while decoding the * image data. */ public void read(final InputStream stream) throws IOException, DataFormatException { decoder.read(stream); } /** * Create a definition for the image so it can be added to a Flash movie. * @param identifier the unique identifier for the image. * @return an ImageTag representing one of the image definitions supported * in Flash. */ public ImageTag defineImage(final int identifier) { return decoder.defineImage(identifier); } /** * Get the ImageDecoder used to decode the image. * * @return the ImageDecoder instance that the factory created to decode the * image. */ public ImageDecoder getDecoder() { return decoder; } }