📄 rescaleop.java
字号:
" components"); } boolean needToConvert = false; // Include alpha if (length > numBands && srcCM.hasAlpha()) { length = numBands+1; } 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; // // Try to use a native BI rescale operation first // if (ImagingLib.filter(this, src, dst) == null) { // // Native BI rescale failed - convert to rasters // WritableRaster srcRaster = src.getRaster(); WritableRaster dstRaster = dst.getRaster(); if (srcCM.hasAlpha()) { if (numBands-1 == length || length == 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 == length || length == 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); } } // // Call the raster filter method // filter(srcRaster, dstRaster); } if (needToConvert) { // ColorModels are not the same ColorConvertOp ccop = new ColorConvertOp(hints); ccop.filter(dst, origDst); } return origDst; } /** * Rescales the pixel data in the source Raster. * If the destination Raster is null, a new Raster will be created. * The source and destination must have the same number of bands. * Otherwise, an IllegalArgumentException is thrown. * Note that the number of scaling factors/offsets in this object must * meet the restrictions stated in the class comments above. * Otherwise, an IllegalArgumentException is thrown. * @param src the <code>Raster</code> to be filtered * @param dst the destination for the filtering operation * or <code>null</code> * @return the filtered <code>WritableRaster</code>. * @throws IllegalArgumentException if <code>src</code> and * <code>dst</code> do not have the same number of bands, * or if the number of scaling factors and offsets in this * <code>RescaleOp</code> do not meet the requirements * stated in the class comments. */ public final WritableRaster filter (Raster src, WritableRaster dst) { int numBands = src.getNumBands(); int width = src.getWidth(); int height = src.getHeight(); int[] srcPix = null; int step = 0; int tidx = 0; // 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"); } else if (numBands != dst.getNumBands()) { // Make sure that the number of bands are equal throw new IllegalArgumentException("Number of bands in src " + numBands + " does not equal number of bands in dest " + dst.getNumBands()); } // Make sure that the arrays match // Make sure that the low/high/constant arrays match if (length != 1 && length != src.getNumBands()) { throw new IllegalArgumentException("Number of scaling constants "+ "does not equal the number of"+ " of bands in the src raster"); } // // Try for a native raster rescale first // if (ImagingLib.filter(this, src, dst) != null) { return dst; } // // Native raster rescale failed. // Try to see if a lookup operation can be used // if (canUseLookup(src, dst)) { int srcNgray = (1 << srcNbits); int dstNgray = (1 << dstNbits); if (dstNgray == 256) { ByteLookupTable lut = createByteLut(scaleFactors, offsets, numBands, srcNgray); LookupOp op = new LookupOp(lut, hints); op.filter(src, dst); } else { ShortLookupTable lut = createShortLut(scaleFactors, offsets, numBands, srcNgray); LookupOp op = new LookupOp(lut, hints); op.filter(src, dst); } } else { // // Fall back to the slow code // if (length > 1) { step = 1; } int sminX = src.getMinX(); int sY = src.getMinY(); int dminX = dst.getMinX(); int dY = dst.getMinY(); int sX; int dX; // // Determine bits per band to determine maxval for clamps. // The min is assumed to be zero. // REMIND: This must change if we ever support signed data types. // int nbits; int dstMax[] = new int[numBands]; int dstMask[] = new int[numBands]; SampleModel dstSM = dst.getSampleModel(); for (int z=0; z<numBands; z++) { nbits = dstSM.getSampleSize(z); dstMax[z] = (1 << nbits) - 1; dstMask[z] = ~(dstMax[z]); } int val; for (int y=0; y < height; y++, sY++, dY++) { dX = dminX; sX = sminX; for (int x = 0; x < width; x++, sX++, dX++) { // Get data for all bands at this x,y position srcPix = src.getPixel(sX, sY, srcPix); tidx = 0; for (int z=0; z<numBands; z++, tidx += step) { val = (int)(srcPix[z]*scaleFactors[tidx] + offsets[tidx]); // Clamp if ((val & dstMask[z]) != 0) { if (val < 0) { val = 0; } else { val = dstMax[z]; } } srcPix[z] = val; } // Put it back for all bands dst.setPixel(dX, dY, srcPix); } } } return dst; } /** * Returns the bounding box of the rescaled destination image. Since * this is not a geometric operation, the bounding box does not * change. */ public final Rectangle2D getBounds2D (BufferedImage src) { return getBounds2D(src.getRaster()); } /** * Returns the bounding box of the rescaled destination Raster. Since * this is not a geometric operation, the bounding box does not * change. * @param src the rescaled destination <code>Raster</code> * @return the bounds of the specified <code>Raster</code>. */ public final Rectangle2D getBounds2D (Raster src) { return src.getBounds(); } /** * Creates a zeroed destination image with the correct size and number of * bands. * @param src Source image for the filter operation. * @param destCM ColorModel of the destination. If null, the * ColorModel of the source will be used. * @return the zeroed-destination image. */ public BufferedImage createCompatibleDestImage (BufferedImage src, ColorModel destCM) { BufferedImage image; if (destCM == null) { ColorModel cm = src.getColorModel(); image = new BufferedImage(cm, src.getRaster().createCompatibleWritableRaster(), cm.isAlphaPremultiplied(), null); } else { int w = src.getWidth(); int h = src.getHeight(); image = new BufferedImage (destCM, destCM.createCompatibleWritableRaster(w, h), destCM.isAlphaPremultiplied(), null); } return image; } /** * Creates a zeroed-destination <code>Raster</code> with the correct * size and number of bands, given this source. * @param src the source <code>Raster</code> * @return the zeroed-destination <code>Raster</code>. */ public WritableRaster createCompatibleDestRaster (Raster src) { return src.createCompatibleWritableRaster(src.getWidth(), src.getHeight()); } /** * Returns the location of the destination point given a * point in the source. If dstPt is non-null, it will * be used to hold the return value. Since this is not a geometric * operation, the srcPt will equal the dstPt. * @param srcPt a point in the source image * @param dstPt the destination point or <code>null</code> * @return the location of the destination point. */ public final Point2D getPoint2D (Point2D srcPt, Point2D dstPt) { if (dstPt == null) { dstPt = new Point2D.Float(); } dstPt.setLocation(srcPt.getX(), srcPt.getY()); return dstPt; } /** * Returns the rendering hints for this op. * @return the rendering hints of this <code>RescaleOp</code>. */ public final RenderingHints getRenderingHints() { return hints; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -