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;
    }
예제 #3
0
  /**
   * 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);
        }
      }
    }
  }