📄 lookupop.java
字号:
/* * @(#)LookupOp.java 1.48 03/01/23 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package java.awt.image;import java.awt.color.ColorSpace;import java.awt.geom.Rectangle2D;import java.awt.Rectangle;import java.awt.RenderingHints;import java.awt.geom.Point2D;import sun.awt.image.ImagingLib;/** * This class implements a lookup operation from the source * to the destination. The LookupTable object may contain a single array * or multiple arrays, subject to the restrictions below. * <p> * For Rasters, the lookup operates on bands. The number of * lookup arrays may be one, in which case the same array is * applied to all bands, or it must equal the number of Source * Raster bands. * <p> * For BufferedImages, the lookup operates on color and alpha components. * The number of lookup arrays may be one, in which case the * same array is applied to all color (but not alpha) components. * Otherwise, the number of lookup arrays may * equal the number of Source color components, in which case no * lookup of the alpha component (if present) is performed. * If neither of these cases apply, the number of lookup arrays * must equal the number of Source color components plus alpha components, * in which case lookup is performed for all color and alpha components. * This allows non-uniform rescaling of multi-band BufferedImages. * <p> * BufferedImage sources with premultiplied alpha data are treated in the same * manner as non-premultiplied images for purposes of the lookup. That is, * the lookup is done per band on the raw data of the BufferedImage source * without regard to whether the data is premultiplied. If a color conversion * is required to the destination ColorModel, the premultiplied state of * both source and destination will be taken into account for this step. * <p> * Images with an IndexColorModel cannot be used. * <p> * If a RenderingHints object is specified in the constructor, the * color rendering hint and the dithering hint may be used when color * conversion is required. * <p> * This class allows the Source to be the same as the Destination. * * @version 10 Feb 1997 * @see LookupTable * @see java.awt.RenderingHints#KEY_COLOR_RENDERING * @see java.awt.RenderingHints#KEY_DITHERING */public class LookupOp implements BufferedImageOp, RasterOp { private LookupTable ltable; private int numComponents; RenderingHints hints; /** * Constructs a <code>LookupOp</code> object given the lookup * table and a <code>RenderingHints</code> object, which might * be <code>null</code>. * @param lookup the specified <code>LookupTable</code> * @param hints the specified <code>RenderingHints</code>, * or <code>null</code> */ public LookupOp(LookupTable lookup, RenderingHints hints) { this.ltable = lookup; this.hints = hints; numComponents = ltable.getNumComponents(); } /** * Returns the <code>LookupTable</code>. * @return the <code>LookupTable</code> of this * <code>LookupOp</code>. */ public final LookupTable getTable() { return ltable; } /** * Performs a lookup operation on a <code>BufferedImage</code>. * If the color model in the source image is not the same as that * in the destination image, the pixels will be converted * in the destination. If the destination image is <code>null</code>, * a <code>BufferedImage</code> will be created with an appropriate * <code>ColorModel</code>. An <code>IllegalArgumentException</code> * might be thrown if the number of arrays in the * <code>LookupTable</code> does not meet the restrictions * stated in the class comment above, or if the source image * has an <code>IndexColorModel</code>. * @param src the <code>BufferedImage</code> to be filtered * @param dst the <code>BufferedImage</code> in which to * store the results of the filter operation * @return the filtered <code>BufferedImage</code>. * @throws IllegalArgumentException if the number of arrays in the * <code>LookupTable</code> does not meet the restrictions * described in the class comments, or if the source image * has an <code>IndexColorModel</code>. */ public final BufferedImage filter(BufferedImage src, BufferedImage dst) { ColorModel srcCM = src.getColorModel(); int numBands = srcCM.getNumColorComponents(); ColorModel dstCM; if (srcCM instanceof IndexColorModel) { throw new IllegalArgumentException("LookupOp cannot be "+ "performed on an indexed image"); } int numComponents = ltable.getNumComponents(); if (numComponents != 1 && numComponents != srcCM.getNumComponents() && numComponents != srcCM.getNumColorComponents()) { throw new IllegalArgumentException("Number of arrays in the "+ " lookup table ("+ numComponents+ " is not compatible with the "+ " src image: "+src); } boolean needToConvert = false; int width = src.getWidth(); int height = src.getHeight(); if (dst == null) { dst = createCompatibleDestImage(src, null); dstCM = srcCM; } else { if (width != dst.getWidth()) { throw new IllegalArgumentException("Src width ("+width+ ") not equal to dst width ("+ dst.getWidth()+")"); } if (height != dst.getHeight()) { throw new IllegalArgumentException("Src height ("+height+ ") not equal to dst height ("+ dst.getHeight()+")"); } dstCM = dst.getColorModel(); if (srcCM.getColorSpace().getType() != dstCM.getColorSpace().getType()) { needToConvert = true; dst = createCompatibleDestImage(src, null); } } BufferedImage origDst = dst; if (ImagingLib.filter(this, src, dst) == null) { // Do it the slow way WritableRaster srcRaster = src.getRaster(); WritableRaster dstRaster = dst.getRaster(); if (srcCM.hasAlpha()) { if (numBands-1 == numComponents || numComponents == 1) { int minx = srcRaster.getMinX(); int miny = srcRaster.getMinY(); int[] bands = new int[numBands-1]; for (int i=0; i < numBands-1; i++) { bands[i] = i; } srcRaster = srcRaster.createWritableChild(minx, miny, srcRaster.getWidth(), srcRaster.getHeight(), minx, miny, bands); } } if (dstCM.hasAlpha()) { int dstNumBands = dstRaster.getNumBands(); if (dstNumBands-1 == numComponents || numComponents == 1) { int minx = dstRaster.getMinX(); int miny = dstRaster.getMinY(); int[] bands = new int[numBands-1]; for (int i=0; i < numBands-1; i++) { bands[i] = i; } dstRaster = dstRaster.createWritableChild(minx, miny, dstRaster.getWidth(), dstRaster.getHeight(), minx, miny, bands); } } filter(srcRaster, dstRaster); } if (needToConvert) { // ColorModels are not the same ColorConvertOp ccop = new ColorConvertOp(hints); ccop.filter(dst, origDst); } return origDst; } /** * Performs a lookup operation on a <code>Raster</code>. * If the destination <code>Raster</code> is <code>null</code>, * a new <code>Raster</code> will be created. * The <code>IllegalArgumentException</code> might be thrown * if the source <code>Raster</code> and the destination * <code>Raster</code> do not have the same * number of bands or if the number of arrays in the * <code>LookupTable</code> does not meet the * restrictions stated in the class comment above. * @param src the source <code>Raster</code> to filter * @param dst the destination <code>WritableRaster</code> for the * filtered <code>src</code> * @return the filtered <code>WritableRaster</code>. * @throws IllegalArgumentException if the source and destinations * rasters do not have the same number of bands, or the * number of arrays in the <code>LookupTable</code> does * not meet the restrictions described in the class comments. * */ public final WritableRaster filter (Raster src, WritableRaster dst) { int numBands = src.getNumBands(); int dstLength = dst.getNumBands(); int height = src.getHeight(); int width = src.getWidth(); int srcPix[] = new int[numBands]; // Create a new destination Raster, if needed if (dst == null) { dst = createCompatibleDestRaster(src); } else if (height != dst.getHeight() || width != dst.getWidth()) { throw new IllegalArgumentException ("Width or height of Rasters do not "+ "match"); } dstLength = dst.getNumBands(); if (numBands != dstLength) { throw new IllegalArgumentException ("Number of channels in the src (" + numBands + ") does not match number of channels" + " in the destination (" + dstLength + ")"); } int numComponents = ltable.getNumComponents(); if (numComponents != 1 && numComponents != src.getNumBands()) { throw new IllegalArgumentException("Number of arrays in the "+ " lookup table ("+ numComponents+ " is not compatible with the "+ " src Raster: "+src); } if (ImagingLib.filter(this, src, dst) != null) { return dst; } // Optimize for cases we know about
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -