JAIUtils.java

00001 
00004 package edu.stanford.hci.r3.util.graphics;
00005 
00006 import java.awt.RenderingHints;
00007 import java.awt.Transparency;
00008 import java.awt.color.ColorSpace;
00009 import java.awt.color.ICC_ColorSpace;
00010 import java.awt.color.ICC_Profile;
00011 import java.awt.image.ColorModel;
00012 import java.awt.image.ComponentColorModel;
00013 import java.awt.image.DataBuffer;
00014 import java.awt.image.PixelInterleavedSampleModel;
00015 import java.awt.image.SampleModel;
00016 import java.awt.image.renderable.ParameterBlock;
00017 import java.io.File;
00018 
00019 import javax.media.jai.BorderExtender;
00020 import javax.media.jai.JAI;
00021 import javax.media.jai.PlanarImage;
00022 import javax.media.jai.TiledImage;
00023 
00032 public class JAIUtils {
00033 
00037         private static final RenderingHints RH_BORDER_REFLECT = new RenderingHints(
00038                         JAI.KEY_BORDER_EXTENDER, BorderExtender.createInstance(BorderExtender.BORDER_REFLECT));
00039 
00047         public static TiledImage createWritableBuffer(int width, int height) {
00048                 return createWritableBuffer(width, height, 4);
00049         }
00050 
00058         private static TiledImage createWritableBuffer(int width, int height, int numBands) {
00059                 // The ColorModel
00060                 final ICC_Profile profile = ICC_Profile.getInstance(ColorSpace.CS_sRGB);
00061                 final boolean hasAlpha = (numBands > 3) ? true : false;
00062                 final ColorModel colorModel = new ComponentColorModel(new ICC_ColorSpace(profile),
00063                                 hasAlpha, /* premultipliedAlpha */
00064                                 false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE);
00065 
00066                 // The SampleModel
00067                 final int defaultTileSize = 128;
00068                 final int[] bandOffsets = new int[numBands];
00069                 for (int i = 0; i < numBands; i++) {
00070                         bandOffsets[i] = numBands - 1 - i;
00071                 }
00072 
00073                 final SampleModel sampleModel = new PixelInterleavedSampleModel(DataBuffer.TYPE_BYTE,
00074                                 defaultTileSize, defaultTileSize /* heightOfTile */, numBands /* pixelStride */,
00075                                 numBands * defaultTileSize, bandOffsets);
00076 
00077                 return new TiledImage(0, 0, width, height, 0, 0, sampleModel, colorModel);
00078         }
00079 
00088         public static TiledImage createWritableBufferWithoutAlpha(int width, int height) {
00089                 return createWritableBuffer(width, height, 3);
00090         }
00091 
00101         public static PlanarImage createZeroImage(int width, int height, int numBands) {
00102                 final Byte[] bandValues = new Byte[numBands];
00103                 for (int i = 0; i < numBands; i++) {
00104                         bandValues[i] = new Byte((byte) 0);
00105                 }
00106                 final ParameterBlock pb = new ParameterBlock();
00107                 pb.add(new Float(width));
00108                 pb.add(new Float(height));
00109                 pb.add(bandValues);
00110                 return (PlanarImage) JAI.create("constant", pb);
00111         }
00112 
00117         public static PlanarImage readJPEG(final File jpegFile) {
00118                 return JAI.create("fileload", jpegFile.getAbsolutePath());
00119         }
00120 
00130         public static PlanarImage scaleImage(PlanarImage src, InterpolationQuality interpQuality,
00131                         float scaleFactorX, float scaleFactorY) {
00132 
00133                 // set the parameters
00134                 final ParameterBlock pb = new ParameterBlock();
00135                 pb.addSource(src);
00136                 pb.add(scaleFactorX);
00137                 pb.add(scaleFactorY);
00138                 pb.add(0.0f);
00139                 pb.add(0.0f);
00140                 pb.add(interpQuality.getInterpolation());
00141 
00142                 // scale!
00143                 return JAI.create("scale", pb, RH_BORDER_REFLECT);
00144         }
00145 
00146         public static PlanarImage scaleImageIteratively(PlanarImage src, float scaleFactorX,
00147                         float scaleFactorY) {
00148                 return scaleImageIterativelyToDimensions(src, InterpolationQuality.BILINEAR, (int) Math
00149                                 .round(src.getWidth() * scaleFactorX), (int) Math.round(src.getHeight()
00150                                 * scaleFactorY));
00151         }
00152 
00162         public static PlanarImage scaleImageIteratively(PlanarImage src,
00163                         InterpolationQuality interpQuality, float scaleFactorX, float scaleFactorY) {
00164                 return scaleImageIterativelyToDimensions(src, interpQuality, (int) Math.round(src
00165                                 .getWidth()
00166                                 * scaleFactorX), (int) Math.round(src.getHeight() * scaleFactorY));
00167         }
00168 
00169         private static PlanarImage scaleImageIterativelyToDimensions(PlanarImage src,
00170                         InterpolationQuality interpQuality, int width, int height) {
00171                 // never scale to lower than...
00172                 double minScale = .5;
00173                 
00174                 // is there a possiblility that it will loop forever?
00175                 // we can prevent it by capping it to 10 iterations...
00176                 int iterations = 0;
00177                 final double targetWidth = (double) width;
00178                 final double targetHeight = (double) height;
00179                 while (!(src.getWidth() == width & src.getHeight() == height) && iterations < 10) {
00180                         float scaleFactorX = (float) Math.max(minScale, targetWidth / src.getWidth());
00181                         float scaleFactorY = (float) Math.max(minScale, (targetHeight / src.getHeight()));
00182                         // System.out.println("Scaling To: " + scaleFactorX + ", " + scaleFactorY);
00183                         src = scaleImage(src, interpQuality, scaleFactorX, scaleFactorY);
00184                         iterations++;
00185                 }
00186                 return src;
00187         }
00188 
00200         public static PlanarImage scaleImageToFit(PlanarImage src, int width, int height) {
00201                 return scaleImageToSize(src, width, height, InterpolationQuality.BICUBIC, true);
00202         }
00203 
00214         public static PlanarImage scaleImageToSize(PlanarImage src, int targetWidth, int targetHeight,
00215                         InterpolationQuality quality, boolean maintainAspectRatio) {
00216                 int oldWidth = src.getWidth();
00217                 int oldHeight = src.getHeight();
00218 
00219                 float testScaleFactorX = (float) targetWidth / (float) oldWidth;
00220                 float testScaleFactorY = (float) targetHeight / (float) oldHeight;
00221 
00222                 float scaleFactorX = 0;
00223                 float scaleFactorY = 0;
00224 
00225                 // if maintaining aspect Ratio, use the smaller of the two scales
00226                 if (maintainAspectRatio) {
00227                         float min = Math.min(testScaleFactorX, testScaleFactorY);
00228                         scaleFactorX = min;
00229                         scaleFactorY = min;
00230                 } else {
00231                         scaleFactorX = testScaleFactorX;
00232                         scaleFactorY = testScaleFactorY;
00233                 }
00234 
00235                 return scaleImageIteratively(src, quality, scaleFactorX, scaleFactorY);
00236         }
00237 
00246         public static void writeImageToJPEG(PlanarImage img, File path) {
00247                 ImageUtils.writeImageToJPEG(img.getAsBufferedImage(), 100, path);
00248         }
00249 
00250 }

Generated on Sat Apr 14 18:21:36 2007 for R3 Paper Toolkit by  doxygen 1.4.7