/* * org.openmicroscopy.shoola.util.image.geom.Factory * *------------------------------------------------------------------------------ * Copyright (C) 2006-2014 University of Dundee. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *------------------------------------------------------------------------------ */ package org.openmicroscopy.shoola.util.image.geom; //Java imports import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Point; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.Toolkit; import java.awt.Transparency; import java.awt.color.ColorSpace; import java.awt.geom.AffineTransform; import java.awt.image.BandedSampleModel; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.ComponentColorModel; import java.awt.image.ConvolveOp; import java.awt.image.DataBuffer; import java.awt.image.DataBufferByte; import java.awt.image.DataBufferInt; import java.awt.image.DirectColorModel; import java.awt.image.Kernel; import java.awt.image.LookupOp; import java.awt.image.Raster; import java.awt.image.RescaleOp; import java.awt.image.SampleModel; import java.awt.image.ShortLookupTable; import java.awt.image.SinglePixelPackedSampleModel; import java.awt.image.WritableRaster; import java.io.File; import javax.imageio.ImageIO; import javax.swing.Icon; import javax.swing.ImageIcon; //Third-party libraries import com.mortennobel.imagescaling.ResampleOp; //Application-internal dependencies import org.openmicroscopy.shoola.util.ui.IconManager; /** * Utility class. Applies some basic filtering methods and affine * transformations to a {@link BufferedImage}. * * @author Jean-Marie Burel      * <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a> * @author <br>Andrea Falconi      * <a href="mailto:a.falconi@dundee.ac.uk"> * a.falconi@dundee.ac.uk</a> * @version 2.2 * <small> * (<b>Internal version:</b> $Revision$ $Date$) * </small> * @since OME2.2 */ public class Factory { /** Identifies the default icon for an image. */ public static final int IMAGE_ICON = IconManager.BROKEN_FILE_96; /** Identifies the default icon for an experimenter. */ public static final int EXPERIMENTER_ICON = IconManager.PERSONAL_96; /** The default width of the icon. */ public static final int DEFAULT_ICON_WIDTH = 16; /** The default height of the icon. */ public static final int DEFAULT_ICON_HEIGHT = 16; /** The default width of a thumbnail. */ public static final int THUMB_DEFAULT_WIDTH = 96; /** The default width of a thumbnail. */ public static final int THUMB_DEFAULT_HEIGHT = 96; /** The red mask. */ public static final int RED_MASK = 0x00ff0000; /** The green mask. */ public static final int GREEN_MASK = 0x0000ff00; /** The blue mask. */ public static final int BLUE_MASK = 0x000000ff; /** The blank mask. */ public static final int BLANK_MASK = 0x00000000; /** Indicates that the text will be added in the top-left corner. */ public static final int LOC_TOP_LEFT = 0; /** Indicates that the text will be added in the top-right corner. */ public static final int LOC_TOP_RIGHT = 1; /** Indicates that the text will be added in the bottom-left corner. */ public static final int LOC_BOTTOM_LEFT = 2; /** Indicates that the text will be added in the bottom-right corner. */ public static final int LOC_BOTTOM_RIGHT = 3; /** The default width and height of a thumbnail. */ public static final int DEFAULT_THUMB = 96; /** Border added to the text. */ private static final int BORDER = 2; /** The default message for the default thumbnail. */ private static final String DEFAULT_TEXT = "No thumbnail"; /** Default text drawn on thumbnail before retrieval. */ private static final String LOADING_TEXT = "Loading..."; /** The RGB masks. */ public static final int[] RGB = {RED_MASK, GREEN_MASK, BLUE_MASK}; /** Color of the rainbow starting * from <code>red</code> to * <code>blue</code>. */ public static final Color[] RED_TO_BLUE_RAINBOW = {Color.red, Color.orange, Color.yellow, Color.green, Color.blue}; /** The violet color. */ public static final Color VIOLET = new Color(138, 43, 226); /** Sharpen filter. */ public static final float[] SHARPEN = { 0.f, -1.f, 0.f, -1.f, 5.f, -1.f, 0.f, -1.f, 0.f}; /** Low pass filter. */ public static final float[] LOW_PASS = { 0.1f, 0.1f, 0.1f, 0.1f, 0.2f, 0.1f, 0.1f, 0.1f, 0.1f }; /** * Resizes an image using a Graphics2D object. * * @param src The image to scale. * @param width The desired width. * @param height The desired height. * @return See above. */ private static Image scaleImage(Image src, int width, int height) { BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g2 = img.createGraphics(); g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); g2.setColor(Color.white); g2.fillRect(0, 0, width, height); g2.drawImage(src, 0, 0, width, height, null); g2.dispose(); src = null; return img; } /** * Creates a default thumbnail image. * * @param width The required width of the thumbnail. * @param height The required height of the thumbnail. * @return See above. */ public static BufferedImage createDefaultImageThumbnail(int width, int height) { if (width == 0) width = THUMB_DEFAULT_WIDTH; if (height == 0) height = THUMB_DEFAULT_HEIGHT; return createDefaultThumbnail(width, height, null); } /** * Creates a default thumbnail image. * * @param icon One of the following {@link #IMAGE_ICON}, * {@link #EXPERIMENTER_ICON} or <code>-1</code>; * @return See above. */ public static BufferedImage createDefaultImageThumbnail(int icon) { IconManager icons = IconManager.getInstance(); ImageIcon img = null; Color background = Color.BLACK; switch (icon) { case IMAGE_ICON: background = null; img = icons.getImageIcon(IconManager.BROKEN_FILE_96); break; case EXPERIMENTER_ICON: background = null; img = icons.getImageIcon(IconManager.PERSONAL_96); break; } if (img == null) return createDefaultThumbnail(96, 96, null); int h = img.getIconHeight(); int w = img.getIconWidth(); BufferedImage thumbPix = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); Graphics2D g = (Graphics2D) thumbPix.getGraphics(); if (background != null) g.setBackground(background); g.drawImage(img.getImage(), 0, 0, null); g.dispose(); img = null; return thumbPix; } /** * Creates a default thumbnail image. * * @param sizeX The width of the thumbnail * @param sizeY The height of the thumbnail. * @param text The text to draw. * @return See above. */ public static BufferedImage createDefaultThumbnail(int sizeX, int sizeY, String text) { BufferedImage thumbPix = new BufferedImage(sizeX, sizeY, BufferedImage.TYPE_INT_RGB); Graphics2D g = (Graphics2D) thumbPix.getGraphics(); g.setColor(Color.BLACK); g.drawRect(0, 0, sizeX, sizeY); if (text != null && text.trim().length() != 0) { FontMetrics fontMetrics = g.getFontMetrics(); int xTxt = BORDER; int yTxt = sizeY/2-fontMetrics.getHeight(); g.setColor(Color.WHITE); g.setFont(g.getFont().deriveFont(Font.BOLD)); g.drawString(text, xTxt, yTxt); g.dispose(); } return thumbPix; } /** * Creates a default thumbnail whose width is {@link #DEFAULT_THUMB} * and height is {@link #DEFAULT_THUMB} and the passed message. * * @param text The text to set. * @return See above, */ public static BufferedImage createDefaultThumbnail(String text) { return createDefaultThumbnail(DEFAULT_THUMB, DEFAULT_THUMB, text); } /** * Creates a default thumbnail whose width is {@link #DEFAULT_THUMB} * and height is {@link #DEFAULT_THUMB} and default message * {@link #LOADING_TEXT}. * * @return See above, */ public static BufferedImage createDefaultThumbnail() { return createDefaultThumbnail(DEFAULT_THUMB, DEFAULT_THUMB, LOADING_TEXT); } /** * Creates a default thumbnail image. * * @param sizeX The width of the thumbnail * @param sizeY The height of the thumbnail. * @return See above. */ public static BufferedImage createDefaultThumbnail(int sizeX, int sizeY) { return createDefaultThumbnail(sizeX, sizeY, DEFAULT_TEXT); } /** * Magnifies the specified {@link BufferedImage}. * * @param img The buffered image to magnify. * @param level The magnification factor. * @param w Extra space, necessary b/c of the lens option. * @return The magnified image. */ public static BufferedImage magnifyImage(BufferedImage img, double level, int w) { return magnifyImage(img, level, w, true); } /** * Magnifies the specified {@link BufferedImage}. * * @param img The buffered image to magnify. * @param level The magnification factor. * @param w Extra space, necessary b/c of the lens option. * @param interpolate Turns interpolation on or off * @return The magnified image. */ public static BufferedImage magnifyImage(BufferedImage img, double level, int w, boolean interpolate) { if (img == null) return null; int width = (int) (img.getWidth()*level)+w; int height = (int) (img.getHeight()*level)+w; // image must be at least 3x3px if (width < 3) width = 3; if (height < 3) height = 3; if (interpolate && img.getWidth() >= 3 && img.getHeight() >= 3) { ResampleOp resampleOp = new ResampleOp(width, height); return resampleOp.filter(img, null); } else { // Use plain Graphics2D, as ResampleOp apparently doesn't provide an option // for disabling interpolation; also have to use Graphics2D for // images < 3px (ResampleOp will fail in this case) BufferedImage result = new BufferedImage(width, height, img.getType()); Graphics2D g = result.createGraphics(); g.getRenderingHints().add(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF)); g.drawImage(img, 0, 0, width, height, 0, 0, img.getWidth(), img.getHeight(), null); return result; } } /** * Magnifies the specified image. * * @param f The magnification factor. * @param img The image to magnify. * @return The magnified image. */ public static BufferedImage magnifyImage(double f, BufferedImage img) { if (img == null) return null; AffineTransform at = new AffineTransform(); at.scale(f, f); int type = img.getType(); if (type == BufferedImage.TYPE_CUSTOM) type = BufferedImage.TYPE_INT_ARGB; Rectangle bounds = img.getRaster().getBounds(); bounds = at.createTransformedShape(bounds).getBounds(); BufferedImage rescaleBuff; rescaleBuff = new BufferedImage(bounds.width, bounds.height, type); //img.getType() Graphics2D g2 = rescaleBuff.createGraphics(); g2.drawImage(img, at, null); g2.dispose(); img.flush(); return rescaleBuff; } /** * Applies a sharpen filter or a low_pass filter. * * @param img The image to transform. * @param filter The filter to apply. * @return The transformed image. */ public static BufferedImage convolveImage(BufferedImage img, float[] filter) { if (img == null) return null; int width = img.getWidth(), height = img.getHeight(); BufferedImage bimg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); RescaleOp rop = new RescaleOp(1, 0.0f, null); rop.filter(img, bimg); // copy the original one Kernel kernel = new Kernel(3, 3, filter); ConvolveOp cop = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null); BufferedImage finalImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); cop.filter(bimg, finalImg); return finalImg; } /** * Creates a buffered image from another buffered image with * some text on top. * * @param img The original buffered image. * @param text The text to add. * @param indexLocation The location of the text. * @param c The color of the text. * @return A new buffered image. */ public static BufferedImage createImageWithText(BufferedImage img, String text, int indexLocation, Color c) { if (img == null) return null; int w = img.getWidth(); int h = img.getHeight(); BufferedImage newImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); Graphics2D g2 = (Graphics2D) newImage.getGraphics(); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); //Paint the original image. g2.drawImage(img, null, 0, 0); //Paint the text FontMetrics fontMetrics = g2.getFontMetrics(); int charWidth = fontMetrics.charWidth('m'); int hFont = fontMetrics.getHeight(); int length = text.length()*charWidth; int xTxt = 0, yTxt = 0; switch (indexLocation) { case LOC_TOP_LEFT: xTxt = BORDER; yTxt = BORDER+hFont; break; case LOC_TOP_RIGHT: xTxt = w-BORDER-length; yTxt = BORDER+hFont; break; case LOC_BOTTOM_LEFT: xTxt = BORDER; yTxt = h-BORDER-hFont; break; case LOC_BOTTOM_RIGHT: xTxt = w-BORDER-length; yTxt = h-BORDER-hFont; } if (c != null) { g2.setColor(c); g2.setFont(g2.getFont().deriveFont(Font.BOLD)); g2.drawString(text, xTxt, yTxt); } img.flush(); return newImage; } /** * Creates a {@link BufferedImage} with a <code>Raster</code> from a * <code>BufferedImage</code> built from a graphics context. * * @param img The image to transform. * @return See above. */ public static BufferedImage createImage(BufferedImage img) { //TODO: ONLY NEED THIS METHOD AS THE TIFF WRITER DOES NOT WORK WITH //BLITTED IMAGES. if (img == null) return null; int sizeY = img.getWidth(); int sizeX = img.getHeight(); DataBufferByte buffer = new DataBufferByte(sizeX*sizeY, 3); DataBuffer dataBuf = img.getRaster().getDataBuffer(); ColorModel cm = img.getColorModel(); int pos = 0; int v = 0; for (int y = 0; y < sizeY; ++y) { for (int x = 0; x < sizeX; ++x) { pos = sizeX*y+x; v = dataBuf.getElem(0, pos); buffer.setElem(0, pos, cm.getRed(v)); buffer.setElem(1, pos, cm.getGreen(v)); buffer.setElem(2, pos, cm.getBlue(v)); } } img.flush(); ComponentColorModel ccm = new ComponentColorModel( ColorSpace.getInstance(ColorSpace.CS_sRGB), null, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE); BandedSampleModel csm = new BandedSampleModel(DataBuffer.TYPE_BYTE, sizeX, sizeY, 3); return new BufferedImage(ccm, Raster.createWritableRaster(csm, buffer, null), false, null); } /** * Creates a {@link BufferedImage} from an Image. * * @param img The Image to convert to a buffered image * @return The buffered image */ public static BufferedImage createImage(Image img) { if (img == null) return null; BufferedImage buff = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB); Graphics gfx = buff.createGraphics(); gfx.drawImage(img, 0, 0, null); gfx.dispose(); img.flush(); return buff; } /** * Creates a {@link BufferedImage} from an Image. * * @param img The BufferedImage to copy to a buffered image * @return The buffered image */ public static BufferedImage copyBufferedImage(BufferedImage img) { if (img == null) return null; BufferedImage buff = new BufferedImage(img.getWidth(null), img.getHeight(null), img.getType()); Graphics gfx = buff.createGraphics(); gfx.drawImage(img, 0, 0, null); gfx.dispose(); img.flush(); return buff; } /** * Creates a buffer image from the specified <code>DataBuffer</code>. * * @param buf The buffer to handle. * @param bits The number of bits in the pixel values. * @param sizeX The width (in pixels) of the region of image data described. * @param sizeY The height (in pixels) of the region of image data * described. * @return See above. */ public static BufferedImage createImage(DataBuffer buf, int bits, int sizeX, int sizeY) { return createImage(buf, bits, RGB, sizeX, sizeY); } /** * Creates a buffer image from the specified <code>DataBuffer</code>. * * @param buf The buffer to handle. * @param bits The number of bits in the pixel values. * @param masks The bit masks for all bands. * @param sizeX The width (in pixels) of the region of image data described. * @param sizeY The height (in pixels) of the region of image data * described. * @return See above. */ public static BufferedImage createImage(DataBuffer buf, int bits, int[] masks, int sizeX, int sizeY) { if (buf instanceof DataBufferInt) { DataBufferInt db = (DataBufferInt) buf; final SampleModel sm = new SinglePixelPackedSampleModel( DataBuffer.TYPE_INT, sizeX, sizeY, sizeX, masks); final WritableRaster raster = Raster.createWritableRaster(sm, db, new Point(0, 0)); final ColorModel colorModel = new DirectColorModel(bits, masks[0], masks[1], masks[2]); return new BufferedImage(colorModel, raster, false, null); } return null; } /** * Creates a buffer image from the specified <code>array</code> of * integers. * * @param buf The array to handle. * @param bits The number of bits in the pixel values. * @param sizeX The width (in pixels) of the region of image data described. * @param sizeY The height (in pixels) of the region of image data * described. * @return See above. */ public static BufferedImage createImage(int[] buf, int bits, int sizeX, int sizeY) { if (buf == null) return null; DataBuffer j2DBuf = new DataBufferInt(buf, sizeX*sizeY); return createImage(j2DBuf, bits, sizeX, sizeY); } /** * Creates a buffer image from the specified <code>array</code> of * integers. * * @param buf The array to handle. * @param bits The number of bits in the pixel values. * @param masks The bit masks for all bands. * @param sizeX The width (in pixels) of the region of image data described. * @param sizeY The height (in pixels) of the region of image data * described. * @return See above. */ public static BufferedImage createImage(int[] buf, int bits, int[] masks, int sizeX, int sizeY) { if (buf == null) return null; DataBuffer j2DBuf = new DataBufferInt(buf, sizeX*sizeY); return createImage(j2DBuf, bits, masks, sizeX, sizeY); } /** * Determines the size of the thumbnail. * * @param sizeX The thumbnail's size along the X-axis. * @param sizeY The thumbnail's size along the Y-axis. * @param realSizeX The real size along the X-axis. * @param realSizeY The real size along the Y-axis. * @return See above. */ public static Dimension computeThumbnailSize(int sizeX, int sizeY, double realSizeX, double realSizeY) { double ratio = 0; int value = 0; if (realSizeY != 0) ratio = realSizeX/realSizeY; if (sizeX <= 0 && sizeY <= 0) return new Dimension(THUMB_DEFAULT_WIDTH, THUMB_DEFAULT_HEIGHT); else if (sizeX <= 0 && sizeY > 0) return new Dimension(THUMB_DEFAULT_WIDTH, sizeY); else if (sizeX > 0 && sizeY <= 0) return new Dimension(sizeX, THUMB_DEFAULT_HEIGHT); if (ratio < 1) { value = (int) (sizeX*ratio); if (value != 0) return new Dimension(value, sizeY); return new Dimension(THUMB_DEFAULT_WIDTH, sizeY); } else if (ratio > 1 && ratio != 0) { value = (int) (sizeY*1/ratio); if (value != 0) return new Dimension(sizeX, value); return new Dimension(sizeX, THUMB_DEFAULT_HEIGHT); } return new Dimension(sizeX, sizeY); } /** * Creates the splash screen logo and login * * @param name The name of the image. * @param path The path to the configuration file. * @return See above. */ public static Icon createIcon(String name, String path) { StringBuffer buf; if (name == null || path == null) return null; buf = new StringBuffer(path); buf.append(File.separatorChar); buf.append(name); try { Image img = Toolkit.getDefaultToolkit().getImage(buf.toString()); if (img == null) return null; Icon icon = new ImageIcon(img); if (icon.getIconHeight() <= 0 || icon.getIconWidth() <= 0) return null; img = null; return icon; } catch (Exception e) {} return null; } /** * Creates the splash screen logo and login * * @param absolutePath The path to the file. * @return See above. */ public static Icon createIcon(String absolutePath) { StringBuffer buf; if (absolutePath == null) return null; buf = new StringBuffer(absolutePath); try { Image img = Toolkit.getDefaultToolkit().getImage(buf.toString()); if (img == null) return null; Icon icon = new ImageIcon(img); if (icon.getIconHeight() <= 0 || icon.getIconWidth() <= 0) return null; return icon; } catch (Exception e) {} return null; } /** * Creates the splash screen logo and login * * @param absolutePath The path to the file. * @param width The width of the icon. * @param height The height of the icon. * @return See above. */ public static Icon createIcon(String absolutePath, int width, int height) { StringBuffer buf; if (absolutePath == null) return null; buf = new StringBuffer(absolutePath); try { Image img = Toolkit.getDefaultToolkit().getImage(buf.toString()); if (img == null) return null; Icon icon = new ImageIcon(img); int w = icon.getIconWidth(); int h = icon.getIconHeight(); if (w <= 0 || h <= 0) return null; if (w > width && h > height) return new ImageIcon(scaleImage(img, width, height)); if (w > width && h <= height) { double r = ((double) w)/h; int value = (int) (w*r); if (value != 0) return new ImageIcon(scaleImage(img, value, height)); return new ImageIcon(scaleImage(img, width, height)); } if (w <= width && h > height) { double r = ((double) w)/h; int value = (int) (h*1/r); if (value != 0) return new ImageIcon(scaleImage(img, width, value)); return new ImageIcon(scaleImage(img, width, height)); } return icon; } catch (Exception e) {} return null; } /** * Scales the passed icon. * * @param icon The icon to scale. * @return See above. */ public static Icon scaleIcon(Icon icon) { return scaleIcon(icon, DEFAULT_ICON_WIDTH, DEFAULT_ICON_HEIGHT); } /** * Scales the passed icon. * * @param icon The icon to scale. * @param width The width of the new icon. * @param height The height of the new icon. * @return See above. */ public static Icon scaleIcon(Icon icon, int width, int height) { if (icon == null) return null; if (width <= 0) width = DEFAULT_ICON_WIDTH; if (height <= 0) height = DEFAULT_ICON_HEIGHT; ImageIcon img = (ImageIcon) icon; BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); Graphics g = bi.createGraphics(); g.drawImage(img.getImage(), 0, 0, width, height, null); return (Icon) (new ImageIcon(bi)); } /** * Scales the passed buffered image. * * @param image The image to scale. * @param width The width of the new image. * @param height The height of the new image. * @return See above. */ public static BufferedImage scaleBufferedImage(BufferedImage image, int width, int height) { if (image == null) return null; if (width <= 0) width = DEFAULT_ICON_WIDTH; if (height <= 0) height = DEFAULT_ICON_HEIGHT; ColorModel cm = image.getColorModel(); WritableRaster r = cm.createCompatibleWritableRaster(width, height); BufferedImage thumbImage = new BufferedImage(cm, r, false, null); // Do the actual scaling and return the result Graphics2D graphics2D = thumbImage.createGraphics(); graphics2D.drawImage(image, 0, 0, width, height, null); return thumbImage; } /** * Scales the passed buffered image. * * @param image The image to scale. * @param maxLength The maxLength of the new image. * @return See above. */ public static BufferedImage scaleBufferedImage(BufferedImage image, int maxLength) { if (image == null) return null; int w = image.getWidth(); int h = image.getHeight(); if (w == maxLength && h == maxLength) return image; Dimension d = computeThumbnailSize(maxLength, maxLength, w, h); ColorModel cm = image.getColorModel(); WritableRaster r = cm.createCompatibleWritableRaster(d.width, d.height); BufferedImage thumbImage = new BufferedImage(cm, r, false, null); // Do the actual scaling and return the result Graphics2D graphics2D = thumbImage.createGraphics(); graphics2D.drawImage(image, 0, 0, d.width, d.height, null); return thumbImage; } /** * Creates a buffered image. * * @param buf The buffer hosting the data. * @param sizeX The image's width. * @param sizeY The image's height. * @param redMask The mask applied on the red component. * @param greenMask The mask applied on the green component. * @param blueMask The mask applied on the blue component. * @return See above. */ public static BufferedImage createBandImage(DataBuffer buf, int sizeX, int sizeY, int redMask, int greenMask, int blueMask) { if (buf == null) return null; int[] masks = {redMask, greenMask, blueMask}; switch (buf.getDataType()) { case DataBuffer.TYPE_BYTE: DataBufferByte bufferByte = (DataBufferByte) buf; byte[] values = bufferByte.getData(); int i = 0, j = 0, l = values.length/3; int[] buffer = new int[l]; while (i<l) buffer[i++] = (values[j++] & 0xff) | (values[j++] & 0xff <<8) | (values[j++] & 0xff <<16); return Factory.createImage(buffer, 24, masks, sizeX, sizeY); case DataBuffer.TYPE_INT: return Factory.createImage(buf, 32, masks, sizeX, sizeY); } return null; } /** * Creates a buffered image. * * @param width The width of the image. * @param height The height of the image. * @param pixels The data to use. * @return See above. */ public static BufferedImage create(int width, int height, int[] pixels) { if (pixels == null) return null; BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); image.setRGB(0, 0, width, height, pixels, 0, width); return image; } /** * Creates a buffered image from the passed image file. * * @param file The file to handle. * @return See above. */ public static BufferedImage createImage(File file) { if (file == null) return null; try { Image img = ImageIO.read(file); BufferedImage image = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB); Graphics2D g = image.createGraphics(); g.drawImage(img, null, null); g.dispose(); img = null; return image; } catch (Exception e) { } return null; } /** * Maps from 4 ints to 4 byte colour. * * @param a The alpha component, value in [0..255]. * @param r The red component, value in [0..255]. * @param g The greed component, value in [0..255]. * @param b The blue component, value in [0..255]. * @return 4 byte int composed of the 4 params, Alpha-Red-Green-Blue. */ public static int makeARGB(int a, int r, int g, int b) { return a << 24 | r << 16 | g << 8 | b; } /** * Creates a buffered image of the specified size using the color * of the rainbow going from the <code>Red</code> to <code>blue</code>. * * @param width The width of the image. * @param height The height of the image. * @return See above. */ public static BufferedImage createGradientImage(int width, int height) { return createGradientImage(width, height, RED_TO_BLUE_RAINBOW); } /** * Creates a buffered image of the specified size using the colors. * * @param width The width of the image. * @param height The height of the image. * @param colors The colors to use. * @return See above. */ public static BufferedImage createGradientImage(int width, int height, Color[] colors) { if (width < 1 || height < 1) return null; if (colors == null || colors.length < 2) colors = RED_TO_BLUE_RAINBOW; BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g2D = (Graphics2D) image.getGraphics(); int x = 0; int y = 0; int n = colors.length; int l = width/(n-1); if (l < 1) l = 1; GradientPaint paint; for (int i = 0; i < colors.length-1; i++) { paint = new GradientPaint(x, y, colors[i], x+l, y, colors[i+1]); g2D.setPaint(paint); g2D.fill(new Rectangle(x, y, l, height)); x += l; } return image; } /** * Applies a look up operation to the specified image. * * @param image The image to handle. * @return See above. */ public static Image makeConstrastDecImage(Image image) { if (image == null) return null; short values[] = new short[256]; short v; for (int i = 0; i < 256; i++) { v = (short) (i/1.5); if (v > 255) v = 255; else if (v < 0) v = 0; values[i] = v; } ShortLookupTable lookupTable = new ShortLookupTable(0, values); BufferedImage img = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB); Graphics g = img.createGraphics(); g.drawImage(image, 0, 0, null); LookupOp lop = new LookupOp(lookupTable, null); lop.filter(img, img); return img; } }