示例#1
0
  /**
   * Test Writing capabilities.
   *
   * @throws FileNotFoundException
   * @throws IOException
   */
  @Test
  public void write() throws IOException, FileNotFoundException {
    if (!isGDALAvailable) {
      return;
    }
    final File outputFile = TestData.temp(this, "writetest.tif", false);
    outputFile.deleteOnExit();
    final File inputFile = TestData.file(this, "utmByte.tif");

    ImageReadParam rparam = new ImageReadParam();
    rparam.setSourceRegion(new Rectangle(1, 1, 300, 500));
    rparam.setSourceSubsampling(1, 2, 0, 0);
    ImageReader reader = new GeoTiffImageReaderSpi().createReaderInstance();
    reader.setInput(inputFile);
    final IIOMetadata metadata = reader.getImageMetadata(0);

    final ParameterBlockJAI pbjImageRead = new ParameterBlockJAI("ImageRead");
    pbjImageRead.setParameter("Input", inputFile);
    pbjImageRead.setParameter("reader", reader);
    pbjImageRead.setParameter("readParam", rparam);

    final ImageLayout l = new ImageLayout();
    l.setTileGridXOffset(0).setTileGridYOffset(0).setTileHeight(256).setTileWidth(256);

    RenderedOp image =
        JAI.create("ImageRead", pbjImageRead, new RenderingHints(JAI.KEY_IMAGE_LAYOUT, l));

    if (TestData.isInteractiveTest()) Viewer.visualizeAllInformation(image, "geotiff");

    // ////////////////////////////////////////////////////////////////
    // preparing to write
    // ////////////////////////////////////////////////////////////////
    final ParameterBlockJAI pbjImageWrite = new ParameterBlockJAI("ImageWrite");
    ImageWriter writer = new GeoTiffImageWriterSpi().createWriterInstance();
    pbjImageWrite.setParameter("Output", outputFile);
    pbjImageWrite.setParameter("writer", writer);
    pbjImageWrite.setParameter("ImageMetadata", metadata);
    pbjImageWrite.setParameter("Transcode", false);
    ImageWriteParam param = new ImageWriteParam(Locale.getDefault());
    param.setSourceRegion(new Rectangle(10, 10, 100, 100));
    param.setSourceSubsampling(2, 1, 0, 0);
    pbjImageWrite.setParameter("writeParam", param);

    pbjImageWrite.addSource(image);
    final RenderedOp op = JAI.create("ImageWrite", pbjImageWrite);
    final ImageWriter writer2 =
        (ImageWriter) op.getProperty(ImageWriteDescriptor.PROPERTY_NAME_IMAGE_WRITER);
    writer2.dispose();

    // ////////////////////////////////////////////////////////////////
    // preparing to read again
    // ////////////////////////////////////////////////////////////////
    final ParameterBlockJAI pbjImageReRead = new ParameterBlockJAI("ImageRead");
    pbjImageReRead.setParameter("Input", outputFile);
    pbjImageReRead.setParameter("Reader", new GeoTiffImageReaderSpi().createReaderInstance());
    final RenderedOp image2 = JAI.create("ImageRead", pbjImageReRead);
    if (TestData.isInteractiveTest()) Viewer.visualizeAllInformation(image2, "geotif2");
    else Assert.assertNotNull(image2.getTiles());
  }
示例#2
0
  /**
   * Test Read on a Paletted Image
   *
   * @throws FileNotFoundException
   * @throws IOException
   */
  @Test
  public void palette() throws FileNotFoundException, IOException {
    if (!isGDALAvailable) {
      return;
    }
    final File outputFile = TestData.temp(this, "writetest.tif", false);
    outputFile.deleteOnExit();
    final File inputFile = TestData.file(this, "paletted.tif");

    ImageReader reader = new GeoTiffImageReaderSpi().createReaderInstance();
    reader.setInput(inputFile);
    final IIOMetadata metadata = reader.getImageMetadata(0);

    final ParameterBlockJAI pbjImageRead = new ParameterBlockJAI("ImageRead");
    pbjImageRead.setParameter("Input", inputFile);
    pbjImageRead.setParameter("reader", reader);

    final ImageLayout l = new ImageLayout();
    l.setTileGridXOffset(0).setTileGridYOffset(0).setTileHeight(256).setTileWidth(256);

    RenderedOp image =
        JAI.create("ImageRead", pbjImageRead, new RenderingHints(JAI.KEY_IMAGE_LAYOUT, l));

    if (TestData.isInteractiveTest()) Viewer.visualizeAllInformation(image, "Paletted image read");

    // ////////////////////////////////////////////////////////////////
    // preparing to write
    // ////////////////////////////////////////////////////////////////
    final ParameterBlockJAI pbjImageWrite = new ParameterBlockJAI("ImageWrite");
    ImageWriter writer = new GeoTiffImageWriterSpi().createWriterInstance();
    pbjImageWrite.setParameter("Output", outputFile);
    pbjImageWrite.setParameter("writer", writer);
    pbjImageWrite.setParameter("ImageMetadata", metadata);
    pbjImageWrite.setParameter("Transcode", false);
    pbjImageWrite.addSource(image);
    final RenderedOp op = JAI.create("ImageWrite", pbjImageWrite);
    final ImageWriter writer2 =
        (ImageWriter) op.getProperty(ImageWriteDescriptor.PROPERTY_NAME_IMAGE_WRITER);
    writer2.dispose();

    // ////////////////////////////////////////////////////////////////
    // preparing to read again
    // ////////////////////////////////////////////////////////////////
    final ParameterBlockJAI pbjImageReRead = new ParameterBlockJAI("ImageRead");
    pbjImageReRead.setParameter("Input", outputFile);
    pbjImageReRead.setParameter("Reader", new GeoTiffImageReaderSpi().createReaderInstance());
    final RenderedOp image2 = JAI.create("ImageRead", pbjImageReRead);
    if (TestData.isInteractiveTest())
      Viewer.visualizeAllInformation(image2, "Paletted image read back after writing");
    else Assert.assertNotNull(image2.getTiles());
    ImageIOUtilities.disposeImage(image2);
    ImageIOUtilities.disposeImage(image);
  }
  @Test
  public void testFourColor() {
    // build a transparent image
    BufferedImage image = new BufferedImage(256, 256, BufferedImage.TYPE_4BYTE_ABGR);
    Graphics g = image.getGraphics();
    g.setColor(Color.WHITE);
    g.fillRect(0, 0, 10, 10);
    g.setColor(Color.RED);
    g.fillRect(10, 0, 10, 10);
    g.setColor(Color.BLUE);
    g.fillRect(20, 0, 10, 10);
    g.setColor(Color.GREEN);
    g.fillRect(30, 0, 10, 10);
    g.dispose();

    //
    // create a palette out of it
    //
    CustomPaletteBuilder builder = new CustomPaletteBuilder(image, 255, 1, 1, 1);
    builder.buildPalette();
    RenderedImage indexed = builder.getIndexedImage();
    assertTrue(indexed.getColorModel() instanceof IndexColorModel);
    IndexColorModel icm = (IndexColorModel) indexed.getColorModel();

    // make sure we have 4 colors + transparent one
    assertEquals(5, icm.getMapSize());

    //
    // now use the JAI op
    //
    assertNotNull(
        (OperationDescriptor)
            JAI.getDefaultInstance()
                .getOperationRegistry()
                .getDescriptor(OperationDescriptor.class, "org.geotools.ColorReduction"));
    ParameterBlockJAI pbj = new ParameterBlockJAI("org.geotools.ColorReduction");
    // I will tile the image in 4 tiles and force parallelism here
    JAI.getDefaultInstance().getTileScheduler().setParallelism(4);
    pbj.addSource(
        new ImageWorker(image)
            .setRenderingHint(
                JAI.KEY_IMAGE_LAYOUT,
                new ImageLayout(image)
                    .setTileGridXOffset(0)
                    .setTileGridYOffset(0)
                    .setTileHeight(64)
                    .setTileWidth(64))
            .tile()
            .getRenderedImage());
    pbj.setParameter("numColors", 255);
    pbj.setParameter("alphaThreshold", 1);
    pbj.setParameter("subsampleX", 1);
    pbj.setParameter("subsampleY", 1);
    indexed = JAI.create("org.geotools.ColorReduction", pbj);
    PlanarImage.wrapRenderedImage(indexed).getTiles();
    assertTrue(indexed.getColorModel() instanceof IndexColorModel);

    // check that we get the same results
    assertEquals(indexed.getColorModel(), icm);
    icm = (IndexColorModel) indexed.getColorModel();

    // make sure we have 4 colors + transparent one
    assertEquals(5, icm.getMapSize());
    assertEquals(5, icm.getMapSize());

    //
    // now use the inversion of color
    //
    assertNotNull(
        (OperationDescriptor)
            JAI.getDefaultInstance()
                .getOperationRegistry()
                .getDescriptor(OperationDescriptor.class, "org.geotools.ColorInversion"));
    pbj = new ParameterBlockJAI("org.geotools.ColorInversion");
    pbj.addSource(
        new ImageWorker(image)
            .setRenderingHint(
                JAI.KEY_IMAGE_LAYOUT,
                new ImageLayout(image)
                    .setTileGridXOffset(0)
                    .setTileGridYOffset(0)
                    .setTileHeight(64)
                    .setTileWidth(64))
            .tile()
            .getRenderedImage());
    pbj.setParameter("quantizationColors", InverseColorMapRasterOp.DEFAULT_QUANTIZATION_COLORS);
    pbj.setParameter("alphaThreshold", 1);
    pbj.setParameter("IndexColorModel", icm);
    indexed = JAI.create("org.geotools.ColorInversion", pbj);
    PlanarImage.wrapRenderedImage(indexed).getTiles();
    assertTrue(indexed.getColorModel() instanceof IndexColorModel);

    // check that we get the same results
    assertEquals(indexed.getColorModel(), icm);
    icm = (IndexColorModel) indexed.getColorModel();

    // make sure we have 4 colors + transparent one
    assertEquals(5, icm.getMapSize());
    assertEquals(5, icm.getMapSize());
  }
  /**
   * For each raster: crop->scale->translate->add to mosaic
   *
   * @param queries
   * @param mosaicGeometry
   * @return
   * @throws IOException
   */
  private RenderedImage createMosaic(
      final List<RasterQueryInfo> queries,
      final GridEnvelope mosaicGeometry,
      final LoggingHelper log)
      throws IOException {

    List<RenderedImage> transformed = new ArrayList<RenderedImage>(queries.size());

    /*
     * Do we need to expand to RGB color space and then create a new colormapped image with the
     * whole mosaic?
     */
    boolean expandCM = queries.size() > 1 && rasterInfo.isColorMapped();
    if (expandCM) {
      LOGGER.fine(
          "Creating mosaic out of "
              + queries.size()
              + " colormapped rasters. The mosaic tiles will be expanded to "
              + "\nRGB space and the resulting mosaic reduced to a new IndexColorModel");
    }

    for (RasterQueryInfo query : queries) {
      RenderedImage image = query.getResultImage();
      log.log(image, query.getRasterId(), "01_original");
      if (expandCM) {
        if (LOGGER.isLoggable(Level.FINER)) {
          LOGGER.finer(
              "Creating color expanded version of tile for raster #" + query.getRasterId());
        }

        /*
         * reformat the image as a 4 band rgba backed by byte data
         */
        image = FormatDescriptor.create(image, Integer.valueOf(DataBuffer.TYPE_BYTE), null);

        log.log(image, query.getRasterId(), "04_1_colorExpanded");
      }

      image = cropToRequiredDimension(image, query.getResultGridRange());
      log.log(image, query.getRasterId(), "02_crop");

      // Raster data = image.getData();
      // image = new BufferedImage(image.getColorModel(), (WritableRaster) data, false, null);
      if (queries.size() == 1) {
        return image;
      }
      final GridEnvelope mosaicLocation = query.getMosaicLocation();
      // scale
      Float scaleX = Float.valueOf(((float) mosaicLocation.getSpan(0) / image.getWidth()));
      Float scaleY = Float.valueOf(((float) mosaicLocation.getSpan(1) / image.getHeight()));
      Float translateX = Float.valueOf(0);
      Float translateY = Float.valueOf(0);

      if (!(Float.valueOf(1.0F).equals(scaleX) && Float.valueOf(1.0F).equals(scaleY))) {
        ParameterBlock pb = new ParameterBlock();
        pb.addSource(image);
        pb.add(scaleX);
        pb.add(scaleY);
        pb.add(translateX);
        pb.add(translateY);
        pb.add(new InterpolationNearest());

        image = JAI.create("scale", pb);
        log.log(image, query.getRasterId(), "03_scale");

        int width = image.getWidth();
        int height = image.getHeight();

        assert mosaicLocation.getSpan(0) == width;
        assert mosaicLocation.getSpan(1) == height;
      }

      if (image.getMinX() != mosaicLocation.getLow(0)
          || image.getMinY() != mosaicLocation.getLow(1)) {
        // translate
        ParameterBlock pb = new ParameterBlock();
        pb.addSource(image);
        pb.add(Float.valueOf(mosaicLocation.getLow(0) - image.getMinX()));
        pb.add(Float.valueOf(mosaicLocation.getLow(1) - image.getMinY()));
        pb.add(null);

        image = JAI.create("translate", pb);
        log.log(image, query.getRasterId(), "04_translate");

        assert image.getMinX() == mosaicLocation.getLow(0)
            : image.getMinX() + " != " + mosaicLocation.getLow(0);
        assert image.getMinY() == mosaicLocation.getLow(1)
            : image.getMinY() + " != " + mosaicLocation.getLow(1);
        assert image.getWidth() == mosaicLocation.getSpan(0)
            : image.getWidth() + " != " + mosaicLocation.getSpan(0);
        assert image.getHeight() == mosaicLocation.getSpan(1)
            : image.getHeight() + " != " + mosaicLocation.getSpan(1);
      }

      transformed.add(image);
    }

    final RenderedImage mosaic;
    if (queries.size() == 1) {
      /*
       * This is besides a very slight perf improvement needed because the JAI mosaic
       * operation truncates floating point raster values to 0 and 1. REVISIT: If there's no
       * workaround for that we should prevent raster catalogs made of floating point rasters
       * and throw an exception as we could not really support that.
       */
      mosaic = transformed.get(0);
    } else {
      /*
       * adapted from RasterLayerResponse.java in the imagemosaic module
       */
      ParameterBlockJAI mosaicParams = new ParameterBlockJAI("Mosaic");
      mosaicParams.setParameter("mosaicType", MosaicDescriptor.MOSAIC_TYPE_OVERLAY);

      // set background values to raster's no-data
      double[] backgroundValues;
      if (expandCM) {
        backgroundValues = new double[] {0, 0, 0, 0};
      } else {
        final int numBands = rasterInfo.getNumBands();
        backgroundValues = new double[numBands];
        final int rasterIndex = 0;
        Number noDataValue;
        for (int bn = 0; bn < numBands; bn++) {
          noDataValue = rasterInfo.getNoDataValue(rasterIndex, bn);
          backgroundValues[bn] = noDataValue.doubleValue();
        }
      }
      mosaicParams.setParameter("backgroundValues", backgroundValues);

      final ImageLayout layout =
          new ImageLayout(
              mosaicGeometry.getLow(0),
              mosaicGeometry.getLow(1),
              mosaicGeometry.getSpan(0),
              mosaicGeometry.getSpan(1));
      final int tileWidth = rasterInfo.getTileDimension(0).width;
      final int tileHeight = rasterInfo.getTileDimension(0).height;
      layout.setTileWidth(tileWidth);
      layout.setTileHeight(tileHeight);

      final RenderingHints hints = new RenderingHints(JAI.KEY_IMAGE_LAYOUT, layout);

      for (RenderedImage img : transformed) {
        mosaicParams.addSource(img);
        log.appendLoggingGeometries(LoggingHelper.MOSAIC_RESULT, img);
      }
      log.log(LoggingHelper.MOSAIC_RESULT);

      LOGGER.fine("Creating mosaic out of " + queries.size() + " raster tiles");
      mosaic = JAI.create("Mosaic", mosaicParams, hints);

      log.log(mosaic, 0L, "05_mosaic_result");
    }
    return mosaic;
  }