lhmc.gui.thumbnail
Class ImageUtils

java.lang.Object
  extended by lhmc.gui.thumbnail.ImageUtils

public class ImageUtils
extends java.lang.Object


Nested Class Summary
 class ImageUtils.BugfixImageWriteParam
          bugfix class as documented in the Java Almanac.
 
Field Summary
static double HUE_UNDEFINED
           
 
Constructor Summary
ImageUtils()
           
 
Method Summary
static double clip01(double value)
          clip the given double to the range [0.0,1.0]
static int clip255(int value)
          clip the given integer to the range [0,255]
static int clip255(long value)
          clip the given long integer to the range [0,255]
static double[] concat(double[] a1, double[] a2)
          concatenate two arrays
static java.awt.image.BufferedImage createBufferedImageARGB(int w, int h)
          wrapper that creates a BufferedImage with TYPE_INT_ARGB
static java.awt.image.BufferedImage createBufferedImageRGB(int w, int h)
          wrapper that creates a BufferedImage with TYPE_INT_RGB
static java.awt.image.BufferedImage getBufferedImage(java.awt.Image image)
           
static java.awt.image.BufferedImage getBufferedImageRGB(java.awt.Image image)
           
static java.awt.Image getCairoBackedImage(java.awt.Image image, java.awt.Component comp)
          use Component.createImage() to convert the given image into an image that can be rendered quickly on both the JDK/JRE and classpath.
static double[] HSV_to_RGB(double h, double s, double v, double[] rgb)
          convert from (hue,saturation,value) to rgb.
static boolean isImageFile(java.lang.String filename)
          check whether the given file is considered an image file.
static java.awt.Image loadImage(java.net.URL url)
           
static java.awt.Image loadImageViaImageIO(java.lang.String pathname)
          load an image (actually BufferedImage) via javax.imageio.ImageIO.read().
static java.awt.Image loadImageViaToolkit(byte[] big, java.awt.image.ImageObserver observer, java.lang.String pathname)
          Convert the given raw image data (byte array) into an Image.
static java.awt.Image loadImageViaToolkit(java.net.URL url, java.awt.image.ImageObserver observer)
          Try to load an Image from the resource called 'pathname'.
static void msg(java.lang.String s)
           
static int packRGB(double r, double g, double b)
          scale from normalized r,g,b components in range[0,1] to a packed integer pixel ARGB with ranges [0,255] and A=0.
static double[] ramp(double x0, double y0, double x1, double y1, int n)
          generate an array of n points that interpolate from (x0,y0) to (x1,y1).
static java.io.ByteArrayOutputStream readStreamIntoBuffer(java.io.InputStream input)
           
static double[] RGB_to_HSV(double r, double g, double b, double[] hsv)
          convert from RGB to HSV colorspace.
static java.awt.image.BufferedImage rotateImageClockwise(java.awt.Image image)
           
static java.awt.image.BufferedImage rotateImageCounterClockwise(java.awt.Image image)
           
static java.awt.image.BufferedImage rotateImageViaTransformOp(java.awt.Image image, double angle)
          rotate the current image via Graphics2D around the given angle (measured in radians).
static void setDebug(boolean b)
           
static void showOutOfMemoryDialog(javax.swing.JFrame parent)
          show a dialog window after an out-of-memory error.
static java.lang.String stripDirectoryNames(java.lang.String pathname)
           
static boolean writeJPEGFile(java.awt.image.BufferedImage image, java.io.File outfile, double quality)
          write the given image to the specifed File in JPEG format at the given quality level.
static boolean writePNGFile(java.awt.image.BufferedImage image, java.io.File outfile)
          write the given image to the specifed file in PNG format.
static boolean writePPMFile(java.awt.image.BufferedImage image, java.io.File outfile)
          write the given image to the specified file in PPM (raw) format.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

HUE_UNDEFINED

public static final double HUE_UNDEFINED
See Also:
Constant Field Values
Constructor Detail

ImageUtils

public ImageUtils()
Method Detail

setDebug

public static void setDebug(boolean b)

isImageFile

public static boolean isImageFile(java.lang.String filename)
check whether the given file is considered an image file. At the moment, this method returns true for files whose names end with ".gif", ".jpg", ".jpeg", ".png", and ".xbm" after conversion to lowercase. FIXME: this method should allow the user to specify the filename patterns instead of using hardcoded values...


stripDirectoryNames

public static java.lang.String stripDirectoryNames(java.lang.String pathname)

readStreamIntoBuffer

public static java.io.ByteArrayOutputStream readStreamIntoBuffer(java.io.InputStream input)

loadImage

public static java.awt.Image loadImage(java.net.URL url)

loadImageViaImageIO

public static java.awt.Image loadImageViaImageIO(java.lang.String pathname)
load an image (actually BufferedImage) via javax.imageio.ImageIO.read(). Note: while ImageIO.read() often works fine, it can be VERY slow for certain JPEG images. The exact cause for this is unknown to me, but it seems to happen for JPEG files with certain ICC color profiles. Reading such images can take on the order of ten seconds (or more) on my Athlon 2600+ with JDK 1.4.2 or 1.5.0, even for small images about 800x600 pixels. Unless this bug is fixed, loadImageViaToolkit() might be the more reliable option. Note: more testing reveals that image loading is pretty fast, but image _rendering_ is slow when using RenderingHints with bilinear interpolation or image quality requested. Rendering is fast without RenderingHints. The 'culprit' images are JPEGs with type BGR and ColorSpace type=5.


loadImageViaToolkit

public static java.awt.Image loadImageViaToolkit(java.net.URL url,
                                                 java.awt.image.ImageObserver observer)
Try to load an Image from the resource called 'pathname'. If the Image cannot be found, or cannot be decoded, we return null. We use a timeout of at most 10000 msec before returning.

The raw image data is loaded via DesignManager.getInputStream() into a ByteArrayOutputStream, and then converted into an Image via java.awt.Toolkit.createImage().


loadImageViaToolkit

public static java.awt.Image loadImageViaToolkit(byte[] big,
                                                 java.awt.image.ImageObserver observer,
                                                 java.lang.String pathname)
Convert the given raw image data (byte array) into an Image. This method calls Toolkit.createImage() to decode the image, which still works better than the javax.imageio methods on most current Java virtual machines (including JDK 1.4.x, 1.5.x, and classpath).

If the cannot be decoded, we return null. We also use a timeout of at most 10000 msec before returning. The optional parameter 'pathname' is only used for (debugging) messages.


createBufferedImageARGB

public static java.awt.image.BufferedImage createBufferedImageARGB(int w,
                                                                   int h)
wrapper that creates a BufferedImage with TYPE_INT_ARGB


createBufferedImageRGB

public static java.awt.image.BufferedImage createBufferedImageRGB(int w,
                                                                  int h)
wrapper that creates a BufferedImage with TYPE_INT_RGB


getBufferedImage

public static java.awt.image.BufferedImage getBufferedImage(java.awt.Image image)

getBufferedImageRGB

public static java.awt.image.BufferedImage getBufferedImageRGB(java.awt.Image image)

getCairoBackedImage

public static java.awt.Image getCairoBackedImage(java.awt.Image image,
                                                 java.awt.Component comp)
use Component.createImage() to convert the given image into an image that can be rendered quickly on both the JDK/JRE and classpath. This method was suggested by Sven de Marothy on the classpath discuss mailing list as a temporary workaround until the classpath image stuff gets mature.


rotateImageClockwise

public static java.awt.image.BufferedImage rotateImageClockwise(java.awt.Image image)

rotateImageCounterClockwise

public static java.awt.image.BufferedImage rotateImageCounterClockwise(java.awt.Image image)

rotateImageViaTransformOp

public static java.awt.image.BufferedImage rotateImageViaTransformOp(java.awt.Image image,
                                                                     double angle)
rotate the current image via Graphics2D around the given angle (measured in radians). FIXME: This method does not yet use correct offsets... should use the full version from hades.models.imaging.RotateFilter.


clip255

public static int clip255(int value)
clip the given integer to the range [0,255]


clip255

public static int clip255(long value)
clip the given long integer to the range [0,255]


clip01

public static double clip01(double value)
clip the given double to the range [0.0,1.0]


ramp

public static double[] ramp(double x0,
                            double y0,
                            double x1,
                            double y1,
                            int n)
generate an array of n points that interpolate from (x0,y0) to (x1,y1). Of course, x1 must not be equal to x0.


concat

public static double[] concat(double[] a1,
                              double[] a2)
concatenate two arrays


RGB_to_HSV

public static double[] RGB_to_HSV(double r,
                                  double g,
                                  double b,
                                  double[] hsv)
convert from RGB to HSV colorspace. The input values RGB are expected to be normalized to range [0,1]. Outputs s and v are normalized to range [0,1], while output h (hue) is normalized to the range [0,6]. If s==0, h is HUE_UNDEFINED. Code rewritten after jgt.akpeters.com/papers/SmithLyons96/hsv_rgb.html hue: red=0 yellow=1 green=2 cyan=3 blue=4 magenta=5


HSV_to_RGB

public static double[] HSV_to_RGB(double h,
                                  double s,
                                  double v,
                                  double[] rgb)
convert from (hue,saturation,value) to rgb. Input h is in the range[0,6] or HUE_UNDEFINED, while inputs s and v and the rgb outputs are normalized to the range [0,1].


packRGB

public static int packRGB(double r,
                          double g,
                          double b)
scale from normalized r,g,b components in range[0,1] to a packed integer pixel ARGB with ranges [0,255] and A=0.


writePNGFile

public static boolean writePNGFile(java.awt.image.BufferedImage image,
                                   java.io.File outfile)
write the given image to the specifed file in PNG format.


writePPMFile

public static boolean writePPMFile(java.awt.image.BufferedImage image,
                                   java.io.File outfile)
write the given image to the specified file in PPM (raw) format.


writeJPEGFile

public static boolean writeJPEGFile(java.awt.image.BufferedImage image,
                                    java.io.File outfile,
                                    double quality)
write the given image to the specifed File in JPEG format at the given quality level. Returns true on success, false on errors. Use quality=0 for smallest file size, quality=1 for best quality. Values outside this range are interpreted as default quality=0.80. This method does not check whether the file already exists; the behaviour might be implementation dependent (e.g., my Linux JDK 1.4.2 silently renames the original file and then writes the given image). Note: the JPEG image quality decreases rapidly with the quality level, everything below the default value of 0.80 should only be used when no further processing is planned for that image. Also note that filesize doesn't really decrease, because the algorithm just changes the JPEG quantization tables. This method is based on the algorithm from the Java Almanac book.


showOutOfMemoryDialog

public static void showOutOfMemoryDialog(javax.swing.JFrame parent)
show a dialog window after an out-of-memory error. FIXME: trying to allocate a JOptionPane with HTML payload might not be a brilliant idea while already out-of-memory. Perhaps we should preallocate the dialog? But this harms startup-time and wastes some memory better used for other things...


msg

public static void msg(java.lang.String s)