package magic.ui.widget.cards.canvas; import javax.imageio.ImageIO; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.Image; import java.awt.RenderingHints; import java.awt.image.BufferedImage; import java.awt.image.ImageObserver; import java.io.IOException; import magic.ui.helpers.ImageHelper; public class ImageHandler { private final ImageObserver observer; private final ImageCache imageCache; public ImageHandler(final ImageObserver observer0) { this.observer = observer0; this.imageCache = new ImageCache(80); } public BufferedImage getImageResource(final String filename, final boolean useCache) { BufferedImage image = null; if (useCache) { image = imageCache.get(filename); if (image == null) { image = loadImageResourceFromFile(filename); imageCache.put(filename, image); } } else { image = loadImageResourceFromFile(filename); } return image; } public BufferedImage getAnnotatedImage(final String id, final Image sourceImage) { final BufferedImage pic = ImageHelper.getCompatibleBufferedImage( sourceImage.getWidth(observer), sourceImage.getHeight(observer)); Graphics2D g2d = (Graphics2D) pic.getGraphics(); g2d.drawImage(sourceImage, 0, 0, null); g2d.setColor(Color.WHITE); g2d.setFont(new Font("dialog", Font.BOLD, 32)); g2d.drawString(id, 40, 110); g2d.dispose(); return pic; } public BufferedImage getScaledImage(final String filename, final int newWidth) { return getScaledImage( getImageResource(filename, true), newWidth); } public BufferedImage getScaledImage(final BufferedImage sourceImage, final int newWidth) { // Only need to scale if required size is different to source. if (newWidth != sourceImage.getWidth()) { // Check whether scaled image is already in cache. final String cacheKey = Integer.toHexString(sourceImage.hashCode()).toUpperCase() + newWidth; BufferedImage scaledImage = imageCache.get(cacheKey); if (scaledImage == null) { // not in cache so will need to scale. final double aspectRatio = (double) sourceImage.getWidth() / sourceImage.getHeight(); final int newHeight = (int) (newWidth / aspectRatio); final boolean useQualityScale = newWidth < sourceImage.getWidth(); scaledImage = ImageHelper.scale( sourceImage, newWidth, newHeight, RenderingHints.VALUE_INTERPOLATION_BILINEAR, useQualityScale); // add scaled image to cache for faster access next time. imageCache.put(cacheKey, scaledImage); } return scaledImage; } else { return sourceImage; } } /** * Loads an image from file and ensures it is in optimum format. * <p> * The images returned by ImageIO are often in custom formats which can draw really, really slowly. For best performance, it's often best to draw any image returned by ImageIO into a new image of the appropriate pixel format for your system. (http://www.jhlabs.com/ip/managed_images.html) */ private BufferedImage loadImageResourceFromFile(final String filename) { final BufferedImage source = loadImage(filename); final BufferedImage buffImage = ImageHelper.getCompatibleBufferedImage(source.getWidth(), source.getHeight()); buffImage.getGraphics().drawImage(source, 0, 0, observer); return buffImage; } private BufferedImage loadImage(final String filename) { BufferedImage img = null; try { img = ImageIO.read(getClass().getClassLoader().getResource(filename)); } catch (IOException e) { System.err.println("ImageHandler.loadImage() : " + e); } if (img == null) { throw new NullPointerException("Failed to load image file: " + filename); } return img; } }