private byte[] getROIData(ROI roi, Rectangle rectIMG) { byte[] dataROI; PlanarImage roiIMG = roi.getAsImage(); Rectangle rectROI = roiIMG.getBounds(); // Forcing to component colormodel in order to avoid packed bits ImageWorker w = new ImageWorker(); w.setImage(roiIMG); w.forceComponentColorModel(); RenderedImage img = w.getRenderedImage(); // BufferedImage test = new BufferedImage(rectIMG.width, rectIMG.height, BufferedImage.TYPE_BYTE_GRAY); ImageLayout2 layout = new ImageLayout2(test); layout.setMinX(img.getMinX()); layout.setMinY(img.getMinY()); layout.setWidth(img.getWidth()); layout.setHeight(img.getHeight()); // Lookup byte[] lut = new byte[256]; lut[255] = 1; lut[1] = 1; LookupTableJAI table = new LookupTableJAI(lut); RenderingHints hints = new RenderingHints(JAI.KEY_IMAGE_LAYOUT, layout); RenderedOp transformed = LookupDescriptor.create(img, table, hints); Graphics2D gc2d = null; // Translation parameters in order to position the ROI data correctly in the Raster Space int trX = -rectIMG.x + rectROI.x - rectIMG.x; int trY = -rectIMG.y + rectROI.y - rectIMG.y; try { gc2d = test.createGraphics(); gc2d.drawRenderedImage(transformed, AffineTransform.getTranslateInstance(trX, trY)); } finally { gc2d.dispose(); } Rectangle testRect = new Rectangle(rectIMG.width, rectIMG.height); DataBufferByte dbRoi = (DataBufferByte) test.getData(testRect).getDataBuffer(); dataROI = dbRoi.getData(); // BufferedImage is stored in memory so the planarImage chain before can be disposed ImageUtilities.disposePlanarImageChain(transformed); // Flush of the BufferedImage test.flush(); return dataROI; }
@Override public RenderedImage postProcessMosaic( RenderedImage mosaic, ROI overallROI, RenderingHints hints) { // force the current image in RGB or Gray final ImageWorker imageWorker = new ImageWorker(mosaic); hints = prepareHints(hints); imageWorker.setRenderingHints(hints); // make sure the mosaic image is either gray of RGB if (!imageWorker.isColorSpaceGRAYScale()) { if (!imageWorker.isColorSpaceRGB()) { imageWorker.forceColorSpaceRGB(); } } imageWorker.forceComponentColorModel(); // todo optimize with paletted imagery // do we already have a alpha band in the input image? if (imageWorker.getRenderedImage().getColorModel().hasAlpha()) { // if so we reuse it applying the ROI on top of it RenderedImage alpha = imageWorker.retainLastBand().getRenderedImage(); RenderedImage maskedAlpha = new ImageWorker(hints) .mosaic( new RenderedImage[] {alpha}, MosaicDescriptor.MOSAIC_TYPE_OVERLAY, null, new ROI[] {overallROI}, null, null) .getRenderedImage(); imageWorker.retainBands(mosaic.getColorModel().getNumColorComponents()); imageWorker.addBand(maskedAlpha, false, true, null); } else { // turn the roi into a single band image and add it to the mosaic as transparency final ImageWorker roiImageWorker = new ImageWorker(overallROI.getAsImage()); roiImageWorker.setRenderingHints(hints); PlanarImage alpha = roiImageWorker.forceComponentColorModel().retainFirstBand().getPlanarImage(); if (!alpha.getBounds().equals(imageWorker.getPlanarImage().getBounds())) { // build final layout and use it for giving the alpha band a simil size and tiling // to the one of the image final ImageLayout layout = new ImageLayout( mosaic.getMinX(), mosaic.getMinY(), mosaic.getWidth(), mosaic.getHeight()); // final SampleModel sampleModel = mosaic.getSampleModel(); layout.setTileHeight(sampleModel.getWidth()).setTileWidth(sampleModel.getHeight()); hints.add(new RenderingHints(JAI.KEY_IMAGE_LAYOUT, layout)); // correct bounds of the current image alpha = new ImageWorker(hints) .mosaic( new RenderedImage[] {alpha}, MosaicDescriptor.MOSAIC_TYPE_OVERLAY, null, new ROI[] {overallROI}, null, null) .getRenderedOperation(); } imageWorker.addBand(alpha, false, true, null); } RenderedImage result = imageWorker.getRenderedImage(); return result; }
/** * Checking if NoData and ROI are defined correctly * * @param indexed * @param image * @param roi * @param nodata * @param destNoData */ private void checkNoDataROI( RenderedImage indexed, RenderedImage image, ROI roi, Range nodata, int destNoData) { // Ensure the dimensions are the same assertEquals(indexed.getMinX(), image.getMinX()); assertEquals(indexed.getMinY(), image.getMinY()); assertEquals(indexed.getWidth(), image.getWidth()); assertEquals(indexed.getHeight(), image.getHeight()); boolean roiExists = roi != null; boolean nodataExists = nodata != null; // Simply ensure no exception is thrown if (!nodataExists && !roiExists) { PlanarImage.wrapRenderedImage(indexed).getTiles(); return; } if (nodataExists) { nodata = RangeFactory.convertToDoubleRange(nodata); } RandomIter roiIter = null; Rectangle roiBounds = null; if (roiExists) { PlanarImage roiIMG = roi.getAsImage(); roiIter = RandomIterFactory.create(roiIMG, null, true, true); roiBounds = roi.getBounds(); } // Else check ROI and NoData RandomIter sourceIter = RandomIterFactory.create(image, null, true, true); RandomIter destIter = RandomIterFactory.create(indexed, null, true, true); // Start the iteration (we iterate only the first band) int w = image.getWidth(); int h = image.getHeight(); int minX = image.getMinX(); int minY = image.getMinY(); int maxX = minX + w; int maxY = minY + h; int limx = minX - image.getTileGridXOffset(); int limy = minY - image.getTileGridYOffset(); Rectangle translated = new Rectangle(limx, limy, w, h); for (int y = minY; y < maxY; y++) { for (int x = minX; x < maxX; x++) { double src = sourceIter.getSampleDouble(x, y, 0); double dest = destIter.getSampleDouble(x, y, 0); boolean valid = true; // ROI Check if (roiExists && !(roiBounds.contains(x, y) && roiIter.getSample(x, y, 0) > 0) && translated.contains(x, y)) { valid = false; } // NoData Check if (nodataExists && nodata.contains(src)) { valid = false; } if (!valid) { assertEquals(destNoData, dest, TOLERANCE); } } } }