BandCombineOppublic class BandCombineOp extends Object implements RasterOpThis class performs an arbitrary linear combination of the bands
in a Raster , using a specified matrix.
The width of the matrix must be equal to the number of bands in the
source Raster , optionally plus one. If there is one more
column in the matrix than the number of bands, there is an implied 1 at the
end of the vector of band samples representing a pixel. The height
of the matrix must be equal to the number of bands in the destination.
For example, a 3-banded Raster might have the following
transformation applied to each pixel in order to invert the second band of
the Raster .
[ 1.0 0.0 0.0 0.0 ] [ b1 ]
[ 0.0 -1.0 0.0 255.0 ] x [ b2 ]
[ 0.0 0.0 1.0 0.0 ] [ b3 ]
[ 1 ]
Note that the source and destination can be the same object. |
Fields Summary |
---|
float[] | matrix | int | nrows | int | ncols | RenderingHints | hints |
Constructors Summary |
---|
public BandCombineOp(float[] matrix, RenderingHints hints)Constructs a BandCombineOp with the specified matrix.
The width of the matrix must be equal to the number of bands in
the source Raster , optionally plus one. If there is one
more column in the matrix than the number of bands, there is an implied
1 at the end of the vector of band samples representing a pixel. The
height of the matrix must be equal to the number of bands in the
destination.
The first subscript is the row index and the second
is the column index. This operation uses none of the currently
defined rendering hints; the RenderingHints argument can be
null.
nrows = matrix.length;
ncols = matrix[0].length;
this.matrix = new float[nrows][];
for (int i=0; i < nrows; i++) {
/* Arrays.copyOf is forgiving of the source array being
* too short, but it is also faster than other cloning
* methods, so we provide our own protection for short
* matrix rows.
*/
if (ncols > matrix[i].length) {
throw new IndexOutOfBoundsException("row "+i+" too short");
}
this.matrix[i] = Arrays.copyOf(matrix[i], ncols);
}
this.hints = hints;
|
Methods Summary |
---|
public java.awt.image.WritableRaster | createCompatibleDestRaster(java.awt.image.Raster src)Creates a zeroed destination Raster with the correct size
and number of bands.
An IllegalArgumentException may be thrown if the number of
bands in the source is incompatible with the matrix. See
the class comments for more details.
int nBands = src.getNumBands();
if ((ncols != nBands) && (ncols != (nBands+1))) {
throw new IllegalArgumentException("Number of columns in the "+
"matrix ("+ncols+
") must be equal to the number"+
" of bands ([+1]) in src ("+
nBands+").");
}
if (src.getNumBands() == nrows) {
return src.createCompatibleWritableRaster();
}
else {
throw new IllegalArgumentException("Don't know how to create a "+
" compatible Raster with "+
nrows+" bands.");
}
| public java.awt.image.WritableRaster | filter(java.awt.image.Raster src, java.awt.image.WritableRaster dst)Transforms the Raster using the matrix specified in the
constructor. An IllegalArgumentException may be thrown if
the number of bands in the source or destination is incompatible with
the matrix. See the class comments for more details.
If the destination is null, it will be created with a number of bands
equalling the number of rows in the matrix. No exception is thrown
if the operation causes a data overflow.
int nBands = src.getNumBands();
if (ncols != nBands && ncols != (nBands+1)) {
throw new IllegalArgumentException("Number of columns in the "+
"matrix ("+ncols+
") must be equal to the number"+
" of bands ([+1]) in src ("+
nBands+").");
}
if (dst == null) {
dst = createCompatibleDestRaster(src);
}
else if (nrows != dst.getNumBands()) {
throw new IllegalArgumentException("Number of rows in the "+
"matrix ("+nrows+
") must be equal to the number"+
" of bands ([+1]) in dst ("+
nBands+").");
}
if (ImagingLib.filter(this, src, dst) != null) {
return dst;
}
int[] pixel = null;
int[] dstPixel = new int[dst.getNumBands()];
float accum;
int sminX = src.getMinX();
int sY = src.getMinY();
int dminX = dst.getMinX();
int dY = dst.getMinY();
int sX;
int dX;
if (ncols == nBands) {
for (int y=0; y < src.getHeight(); y++, sY++, dY++) {
dX = dminX;
sX = sminX;
for (int x=0; x < src.getWidth(); x++, sX++, dX++) {
pixel = src.getPixel(sX, sY, pixel);
for (int r=0; r < nrows; r++) {
accum = 0.f;
for (int c=0; c < ncols; c++) {
accum += matrix[r][c]*pixel[c];
}
dstPixel[r] = (int) accum;
}
dst.setPixel(dX, dY, dstPixel);
}
}
}
else {
// Need to add constant
for (int y=0; y < src.getHeight(); y++, sY++, dY++) {
dX = dminX;
sX = sminX;
for (int x=0; x < src.getWidth(); x++, sX++, dX++) {
pixel = src.getPixel(sX, sY, pixel);
for (int r=0; r < nrows; r++) {
accum = 0.f;
for (int c=0; c < nBands; c++) {
accum += matrix[r][c]*pixel[c];
}
dstPixel[r] = (int) (accum+matrix[r][nBands]);
}
dst.setPixel(dX, dY, dstPixel);
}
}
}
return dst;
| public final java.awt.geom.Rectangle2D | getBounds2D(java.awt.image.Raster src)Returns the bounding box of the transformed destination. Since
this is not a geometric operation, the bounding box is the same for
the source and destination.
An IllegalArgumentException may be thrown if the number of
bands in the source is incompatible with the matrix. See
the class comments for more details.
return src.getBounds();
| public final float[][] | getMatrix()Returns a copy of the linear combination matrix.
float[][] ret = new float[nrows][];
for (int i = 0; i < nrows; i++) {
ret[i] = Arrays.copyOf(matrix[i], ncols);
}
return ret;
| public final java.awt.geom.Point2D | getPoint2D(java.awt.geom.Point2D srcPt, java.awt.geom.Point2D dstPt)Returns the location of the corresponding destination point given a
point in the source Raster . If dstPt is
specified, it is used to hold the return value.
Since this is not a geometric operation, the point returned
is the same as the specified srcPt .
if (dstPt == null) {
dstPt = new Point2D.Float();
}
dstPt.setLocation(srcPt.getX(), srcPt.getY());
return dstPt;
| public final java.awt.RenderingHints | getRenderingHints()Returns the rendering hints for this operation.
return hints;
|
|