Beispiel #1
0
  public BufferedImage readTile(int imageIndex, int tileX, int tileY) throws IOException {

    int w = getWidth(imageIndex);
    int h = getHeight(imageIndex);
    int tw = getTileWidth(imageIndex);
    int th = getTileHeight(imageIndex);

    int x = tw * tileX;
    int y = th * tileY;

    if (tileX < 0 || tileY < 0 || x >= w || y >= h) {
      throw new IllegalArgumentException("Tile indices are out of bounds!");
    }

    if (x + tw > w) {
      tw = w - x;
    }

    if (y + th > h) {
      th = h - y;
    }

    ImageReadParam param = getDefaultReadParam();
    Rectangle tileRect = new Rectangle(x, y, tw, th);
    param.setSourceRegion(tileRect);

    return read(imageIndex, param);
  }
Beispiel #2
0
  @Test
  public void testDataTypes() throws IOException, FileNotFoundException {
    if (!isGDALAvailable) {
      return;
    }
    final List<String> fileList = new ArrayList<String>(4);
    fileList.add("paletted.tif");
    fileList.add("utmByte.tif");
    fileList.add("utmInt16.tif");
    fileList.add("utmInt32.tif");
    fileList.add("utmFloat32.tif");
    fileList.add("utmFloat64.tif");

    for (String fileName : fileList) {
      final ImageReadParam irp = new ImageReadParam();
      final File inputFile = TestData.file(this, fileName);
      irp.setSourceSubsampling(1, 1, 0, 0);
      ImageReader reader = new GeoTiffImageReaderSpi().createReaderInstance();
      reader.setInput(inputFile);
      final RenderedImage image = reader.readAsRenderedImage(0, irp);
      if (TestData.isInteractiveTest()) Viewer.visualizeAllInformation(image, fileName);
      if (!fileName.contains("paletted")) {
        Assert.assertEquals(256, image.getHeight());
        Assert.assertEquals(256, image.getWidth());
      } else {
        Assert.assertEquals(128, image.getHeight());
        Assert.assertEquals(128, image.getWidth());
      }

      reader.dispose();
    }
  }
Beispiel #3
0
 private BufferedImage getImage(File file) {
   ImageInputStream iis = null;
   BufferedImage image = null;
   try {
     iis = ImageIO.createImageInputStream(file);
     Iterator<ImageReader> it = ImageIO.getImageReaders(iis);
     if (!it.hasNext()) throw new UnsupportedOperationException("No image reader fround.");
     ImageReader reader = it.next();
     reader.setInput(iis);
     int scaleFactor;
     if (reader.getWidth(0) >= reader.getHeight(0))
       scaleFactor = Math.round(((float) reader.getWidth(0)) / MAX_SIZE);
     else scaleFactor = Math.round(((float) reader.getHeight(0)) / MAX_SIZE);
     ImageReadParam param = reader.getDefaultReadParam();
     param.setSourceSubsampling(scaleFactor, scaleFactor, 0, 0);
     image = reader.read(0, param);
   } catch (IOException e) {
     e.printStackTrace();
   } finally {
     if (iis != null)
       try {
         iis.close();
       } catch (IOException e) {
         e.printStackTrace();
       }
   }
   return image;
 }
  public void readDescendingRasterBand(
      final int sourceOffsetX,
      final int sourceOffsetY,
      final int sourceStepX,
      final int sourceStepY,
      final ProductData destBuffer,
      final int destOffsetX,
      final int destOffsetY,
      final int destWidth,
      final int destHeight,
      final int imageID,
      final ImageIOFile img,
      final int bandSampleOffset,
      final boolean isAntennaPointingRight)
      throws IOException {

    final Raster data;

    synchronized (dataDir) {
      final ImageReader reader = img.getReader();
      final ImageReadParam param = reader.getDefaultReadParam();
      param.setSourceSubsampling(
          sourceStepX, sourceStepY, sourceOffsetX % sourceStepX, sourceOffsetY % sourceStepY);

      final RenderedImage image = reader.readAsRenderedImage(0, param);
      if (flipToSARGeometry && isAntennaPointingRight) { // flip the image left to right
        data =
            image.getData(
                new Rectangle(
                    img.getSceneWidth() - destOffsetX - destWidth,
                    destOffsetY,
                    destWidth,
                    destHeight));
      } else {
        data = image.getData(new Rectangle(destOffsetX, destOffsetY, destWidth, destHeight));
      }
    }

    final DataBuffer dataBuffer = data.getDataBuffer();
    final SampleModel sampleModel = data.getSampleModel();
    final int sampleOffset = imageID + bandSampleOffset;

    if (flipToSARGeometry && isAntennaPointingRight) { // flip the image left to right
      final int[] dArray = new int[destWidth * destHeight];
      sampleModel.getSamples(0, 0, destWidth, destHeight, sampleOffset, dArray, dataBuffer);

      int srcStride, destStride;
      for (int r = 0; r < destHeight; r++) {
        srcStride = r * destWidth;
        destStride = r * destWidth + destWidth;
        for (int c = 0; c < destWidth; c++) {
          destBuffer.setElemIntAt(destStride - c - 1, dArray[srcStride + c]);
        }
      }
    } else { // no flipping is needed
      sampleModel.getSamples(
          0, 0, destWidth, destHeight, sampleOffset, (int[]) destBuffer.getElems(), dataBuffer);
    }
  }
Beispiel #5
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());
  }
Beispiel #6
0
  protected static BufferedImage getDestination(
      ImageReadParam param, Iterator imageTypes, int width, int height) throws IIOException {
    if (imageTypes == null || !imageTypes.hasNext()) {
      throw new IllegalArgumentException("imageTypes null or empty!");
    }

    BufferedImage dest = null;
    ImageTypeSpecifier imageType = null;

    // If param is non-null, use it
    if (param != null) {
      // Try to get the image itself
      dest = param.getDestination();
      if (dest != null) {
        return dest;
      }

      // No image, get the image type
      imageType = param.getDestinationType();
    }

    // No info from param, use fallback image type
    if (imageType == null) {
      Object o = imageTypes.next();
      if (!(o instanceof ImageTypeSpecifier)) {
        throw new IllegalArgumentException("Non-ImageTypeSpecifier retrieved from imageTypes!");
      }
      imageType = (ImageTypeSpecifier) o;
    } else {
      boolean foundIt = false;
      while (imageTypes.hasNext()) {
        ImageTypeSpecifier type = (ImageTypeSpecifier) imageTypes.next();
        if (type.equals(imageType)) {
          foundIt = true;
          break;
        }
      }

      if (!foundIt) {
        throw new IIOException("Destination type from ImageReadParam does not match!");
      }
    }

    Rectangle srcRegion = new Rectangle(0, 0, 0, 0);
    Rectangle destRegion = new Rectangle(0, 0, 0, 0);
    computeRegions(param, width, height, null, srcRegion, destRegion);

    int destWidth = destRegion.x + destRegion.width;
    int destHeight = destRegion.y + destRegion.height;
    // Create a new image based on the type specifier

    if ((long) destWidth * destHeight > Integer.MAX_VALUE) {
      throw new IllegalArgumentException("width*height > Integer.MAX_VALUE!");
    }

    return imageType.createBufferedImage(destWidth, destHeight);
  }
Beispiel #7
0
 private ImageReadParam decompressParam(ImageReadParam param) {
   ImageReadParam decompressParam = decompressor.getDefaultReadParam();
   ImageTypeSpecifier imageType = param.getDestinationType();
   BufferedImage dest = param.getDestination();
   if (isRLELossless() && imageType == null && dest == null)
     imageType = createImageType(bitsStored, dataType, true);
   decompressParam.setDestinationType(imageType);
   decompressParam.setDestination(dest);
   return decompressParam;
 }
Beispiel #8
0
  private void prepareRead(int imageIndex, ImageReadParam param) throws IOException {
    if (stream == null) {
      throw new IllegalStateException("Input not set!");
    }

    // A null ImageReadParam means we use the default
    if (param == null) {
      param = getDefaultReadParam();
    }

    this.imageReadParam = param;

    seekToImage(imageIndex);

    this.tileOrStripWidth = getTileOrStripWidth();
    this.tileOrStripHeight = getTileOrStripHeight();
    this.planarConfiguration = getPlanarConfiguration();

    this.sourceBands = param.getSourceBands();
    if (sourceBands == null) {
      sourceBands = new int[numBands];
      for (int i = 0; i < numBands; i++) {
        sourceBands[i] = i;
      }
    }

    // Initialize the destination image
    Iterator imageTypes = getImageTypes(imageIndex);
    ImageTypeSpecifier theImageType = ImageUtil.getDestinationType(param, imageTypes);

    int destNumBands = theImageType.getSampleModel().getNumBands();

    this.destinationBands = param.getDestinationBands();
    if (destinationBands == null) {
      destinationBands = new int[destNumBands];
      for (int i = 0; i < destNumBands; i++) {
        destinationBands[i] = i;
      }
    }

    if (sourceBands.length != destinationBands.length) {
      throw new IllegalArgumentException("sourceBands.length != destinationBands.length");
    }

    for (int i = 0; i < sourceBands.length; i++) {
      int sb = sourceBands[i];
      if (sb < 0 || sb >= numBands) {
        throw new IllegalArgumentException("Source band out of range!");
      }
      int db = destinationBands[i];
      if (db < 0 || db >= destNumBands) {
        throw new IllegalArgumentException("Destination band out of range!");
      }
    }
  }
Beispiel #9
0
 /*
  * 图片裁剪通用接口
  */
 public static void cutImage(String src, String dest, int x, int y, int w, int h)
     throws IOException {
   Iterator iterator = ImageIO.getImageReadersByFormatName("jpg");
   ImageReader reader = (ImageReader) iterator.next();
   InputStream in = new FileInputStream(src);
   ImageInputStream iis = ImageIO.createImageInputStream(in);
   reader.setInput(iis, true);
   ImageReadParam param = reader.getDefaultReadParam();
   Rectangle rect = new Rectangle(x, y, w, h);
   param.setSourceRegion(rect);
   BufferedImage bi = reader.read(0, param);
   ImageIO.write(bi, "jpg", new File(dest));
 }
Beispiel #10
0
 /*
  * 图片裁剪二分之一
  */
 public static void cutHalfImage(String src, String dest) throws IOException {
   Iterator iterator = ImageIO.getImageReadersByFormatName("jpg");
   ImageReader reader = (ImageReader) iterator.next();
   InputStream in = new FileInputStream(src);
   ImageInputStream iis = ImageIO.createImageInputStream(in);
   reader.setInput(iis, true);
   ImageReadParam param = reader.getDefaultReadParam();
   int imageIndex = 0;
   int width = reader.getWidth(imageIndex) / 2;
   int height = reader.getHeight(imageIndex) / 2;
   Rectangle rect = new Rectangle(width / 2, height / 2, width, height);
   param.setSourceRegion(rect);
   BufferedImage bi = reader.read(0, param);
   ImageIO.write(bi, "jpg", new File(dest));
 }
Beispiel #11
0
  @Test
  public void imageReadParam2() throws IOException {
    Iterator<ImageReader> itr = ImageIO.getImageReadersByFormatName("jpg");
    ImageReader imageReader = itr.next();

    ImageInputStream imageInputStream = ImageIO.createImageInputStream(new File(SRCIMG));
    imageReader.setInput(imageInputStream, true);

    ImageReadParam imageReadParam = imageReader.getDefaultReadParam();
    imageReadParam.setSourceSubsampling(3, 3, 0, 0);

    BufferedImage bufferedImage = imageReader.read(0, imageReadParam);

    boolean b = ImageIO.write(bufferedImage, "jpg", new File(CONTEXT + "1.jpg"));
    System.out.println(b);
  }
  public static void main(String[] args) throws IOException {
    PCXImageReader reader = new PCXImageReader(null);

    for (String arg : args) {
      File in = new File(arg);
      reader.setInput(ImageIO.createImageInputStream(in));

      ImageReadParam param = reader.getDefaultReadParam();
      param.setDestinationType(reader.getImageTypes(0).next());
      //            param.setSourceSubsampling(2, 3, 0, 0);
      //            param.setSourceSubsampling(2, 1, 0, 0);
      //
      //            int width = reader.getWidth(0);
      //            int height = reader.getHeight(0);
      //
      //            param.setSourceRegion(new Rectangle(width / 4, height / 4, width / 2, height /
      // 2));
      //            param.setSourceRegion(new Rectangle(width / 2, height / 2));
      //            param.setSourceRegion(new Rectangle(width / 2, height / 2, width / 2, height /
      // 2));

      System.err.println("header: " + reader.header);

      BufferedImage image = reader.read(0, param);

      System.err.println("image: " + image);

      showIt(image, in.getName());

      new XMLSerializer(System.out, System.getProperty("file.encoding"))
          .serialize(
              reader
                  .getImageMetadata(0)
                  .getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName),
              false);

      //            File reference = new File(in.getParent() + "/../reference",
      // in.getName().replaceAll("\\.p(a|b|g|p)m", ".png"));
      //            if (reference.exists()) {
      //                System.err.println("reference.getAbsolutePath(): " +
      // reference.getAbsolutePath());
      //                showIt(ImageIO.read(reference), reference.getName());
      //            }

      //            break;
    }
  }
  /**
   * This method is responsible for evaluating possible subsampling factors once the best resolution
   * level has been found, in case we have support for overviews, or starting from the original
   * coverage in case there are no overviews available.
   *
   * <p>Anyhow this method should not be called directly but subclasses should make use of the
   * setReadParams method instead in order to transparently look for overviews.
   *
   * @param imageChoice
   * @param readP
   * @param requestedRes
   */
  protected final void decimationOnReadingControl(
      String coverageName, Integer imageChoice, ImageReadParam readP, double[] requestedRes) {
    {
      int w, h;
      double selectedRes[] = new double[2];
      final int choice = imageChoice.intValue();
      if (choice == 0) {
        // highest resolution
        w = getOriginalGridRange(coverageName).getSpan(0);
        h = getOriginalGridRange(coverageName).getSpan(1);
        selectedRes[0] = getHighestRes()[0];
        selectedRes[1] = getHighestRes()[1];
      } else {
        // some overview
        selectedRes[0] = overViewResolutions[choice - 1][0];
        selectedRes[1] = overViewResolutions[choice - 1][1];
        w = (int) Math.round(getOriginalEnvelope(coverageName).getSpan(0) / selectedRes[0]);
        h = (int) Math.round(getOriginalEnvelope(coverageName).getSpan(1) / selectedRes[1]);
      }
      // /////////////////////////////////////////////////////////////////////
      // DECIMATION ON READING
      // Setting subsampling factors with some checkings
      // 1) the subsampling factors cannot be zero
      // 2) the subsampling factors cannot be such that the w or h are
      // zero
      // /////////////////////////////////////////////////////////////////////
      if (requestedRes == null) {
        readP.setSourceSubsampling(1, 1, 0, 0);

      } else {
        int subSamplingFactorX = (int) Math.floor(requestedRes[0] / selectedRes[0]);
        subSamplingFactorX = subSamplingFactorX == 0 ? 1 : subSamplingFactorX;

        while (w / subSamplingFactorX <= 0 && subSamplingFactorX >= 0) subSamplingFactorX--;
        subSamplingFactorX = subSamplingFactorX == 0 ? 1 : subSamplingFactorX;

        int subSamplingFactorY = (int) Math.floor(requestedRes[1] / selectedRes[1]);
        subSamplingFactorY = subSamplingFactorY == 0 ? 1 : subSamplingFactorY;

        while (h / subSamplingFactorY <= 0 && subSamplingFactorY >= 0) subSamplingFactorY--;
        subSamplingFactorY = subSamplingFactorY == 0 ? 1 : subSamplingFactorY;

        readP.setSourceSubsampling(subSamplingFactorX, subSamplingFactorY, 0, 0);
      }
    }
  }
  private synchronized Raster readRect(
      int sourceOffsetX,
      int sourceOffsetY,
      int sourceStepX,
      int sourceStepY,
      int destOffsetX,
      int destOffsetY,
      int destWidth,
      int destHeight)
      throws IOException {
    ImageReadParam readParam = imageReader.getDefaultReadParam();
    int subsamplingXOffset = sourceOffsetX % sourceStepX;
    int subsamplingYOffset = sourceOffsetY % sourceStepY;
    readParam.setSourceSubsampling(
        sourceStepX, sourceStepY, subsamplingXOffset, subsamplingYOffset);
    RenderedImage subsampledImage = imageReader.readAsRenderedImage(FIRST_IMAGE, readParam);

    return subsampledImage.getData(new Rectangle(destOffsetX, destOffsetY, destWidth, destHeight));
  }
Beispiel #15
0
  /**
   * Test Read without exploiting JAI-ImageIO Tools
   *
   * @throws FileNotFoundException
   * @throws IOException
   */
  @Test
  public void manualRead() throws IOException, FileNotFoundException {
    if (!isGDALAvailable) {
      return;
    }
    final ImageReadParam irp = new ImageReadParam();

    // Reading a simple GrayScale image
    String fileName = "utmByte.tif";
    final File inputFile = TestData.file(this, fileName);
    irp.setSourceSubsampling(2, 2, 0, 0);
    ImageReader reader = new GeoTiffImageReaderSpi().createReaderInstance();
    reader.setInput(inputFile);
    final RenderedImage image = reader.readAsRenderedImage(0, irp);
    if (TestData.isInteractiveTest()) Viewer.visualizeAllInformation(image, fileName);
    Assert.assertEquals(128, image.getWidth());
    Assert.assertEquals(128, image.getHeight());
    reader.dispose();
  }
Beispiel #16
0
  @Test
  public void imageReadParam() throws IOException {
    Iterator<ImageReader> itr = ImageIO.getImageReadersByFormatName("jpg");
    ImageReader imageReader = itr.next();

    ImageInputStream imageInputStream = ImageIO.createImageInputStream(new File(SRCIMG));

    imageReader.setInput(imageInputStream, true);

    ImageReadParam imageReadParam = imageReader.getDefaultReadParam();
    int halfWidth = imageReader.getWidth(0) / 2;
    int halfHeight = imageReader.getHeight(0) / 2;
    Rectangle rectangle = new Rectangle(0, 0, halfWidth, halfHeight);
    imageReadParam.setSourceRegion(rectangle);

    BufferedImage bufferedImage = imageReader.read(0, imageReadParam);
    System.out.println(bufferedImage.getWidth());

    boolean result = ImageIO.write(bufferedImage, "png", new File(CONTEXT + "999.png"));
    System.out.println(result);
  }
Beispiel #17
0
  /**
   * 图片截取
   *
   * @param file
   * @param newName
   * @param path
   * @param x
   * @param y
   * @param width
   * @param height
   * @return author:caobo date:Oct 14, 2009 12:38:05 PM
   */
  public static File cutting(
      File file, String newName, String path, int x, int y, int width, int height) {
    ImageOutputStream out = null;
    InputStream is = null;
    ImageInputStream iis = null;
    try {
      String endName = file.getName();
      endName = endName.substring(endName.lastIndexOf(".") + 1);
      Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName(endName);
      ImageReader reader = (ImageReader) readers.next();
      is = new FileInputStream(file);
      iis = ImageIO.createImageInputStream(is);
      reader.setInput(iis, true);

      ImageReadParam param = reader.getDefaultReadParam();
      Rectangle rect = new Rectangle(x, y, width, height);
      param.setSourceRegion(rect);
      BufferedImage bi = reader.read(0, param);
      File newFile = new File(path);

      if (!newFile.exists()) newFile.mkdirs();
      newFile = new File(path, newName);
      out = ImageIO.createImageOutputStream(new FileOutputStream(newFile));
      ImageIO.write(bi, endName, out);
      file = newFile;
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      try {
        iis.close();
        is.close();
        out.close();
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
    return file;
  }
  private BufferedImage scaleDown(
      final ImageInputStream inputStream, final int maxWidth, final int maxHeight)
      throws IOException {
    final Iterator<ImageReader> readers = ImageIO.getImageReaders(inputStream);
    if (!readers.hasNext()) {
      throw new IOException("No ImageReader available for the given ImageInputStream");
    }
    // Use the first reader, next will instantiate ImageReader which needs to be disposed
    final ImageReader reader = readers.next();
    try {
      final ImageReadParam param = reader.getDefaultReadParam();
      reader.setInput(inputStream);

      final Dimension original = new Dimension(reader.getWidth(0), reader.getHeight(0));
      final Dimension target = new Dimension(maxWidth, maxHeight);
      final int ratio = maintainAspectRatio(original, target);
      param.setSourceSubsampling(ratio, ratio, 0, 0);

      return reader.read(0, param);
    } finally {
      reader.dispose();
    }
  }
  public TIFFRenderedImage(
      TIFFImageReader reader, int imageIndex, ImageReadParam readParam, int width, int height)
      throws IOException {
    this.reader = reader;
    this.imageIndex = imageIndex;
    this.tileParam = cloneImageReadParam(readParam, false);

    this.subsampleX = tileParam.getSourceXSubsampling();
    this.subsampleY = tileParam.getSourceYSubsampling();

    this.isSubsampling = this.subsampleX != 1 || this.subsampleY != 1;

    this.width = width / subsampleX;
    this.height = height / subsampleY;

    // If subsampling is being used, we may not match the
    // true tile grid exactly, but everything should still work
    this.tileWidth = reader.getTileWidth(imageIndex) / subsampleX;
    this.tileHeight = reader.getTileHeight(imageIndex) / subsampleY;

    Iterator iter = reader.getImageTypes(imageIndex);
    this.its = (ImageTypeSpecifier) iter.next();
    tileParam.setDestinationType(its);
  }
  // This method needs to be synchronized as it updates the instance
  // variable 'tileParam'.
  public synchronized WritableRaster read(Rectangle rect) {
    // XXX Does this need to consider the subsampling offsets or is
    // that handled implicitly by the reader?
    tileParam.setSourceRegion(
        isSubsampling
            ? new Rectangle(
                subsampleX * rect.x,
                subsampleY * rect.y,
                subsampleX * rect.width,
                subsampleY * rect.height)
            : rect);

    try {
      BufferedImage bi = reader.read(imageIndex, tileParam);
      WritableRaster ras = bi.getRaster();
      return ras.createWritableChild(0, 0, ras.getWidth(), ras.getHeight(), rect.x, rect.y, null);
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }
  /**
   * Creates a copy of <code>param</code>. The source subsampling and and bands settings and the
   * destination bands and offset settings are copied. If <code>param</code> is a <code>
   * TIFFImageReadParam</code> then the <code>TIFFDecompressor</code> and <code>TIFFColorConverter
   * </code> settings are also copied; otherwise they are explicitly set to <code>null</code>.
   *
   * @param param the parameters to be copied.
   * @param copyTagSets whether the <code>TIFFTagSet</code> settings should be copied if set.
   * @return copied parameters.
   */
  private ImageReadParam cloneImageReadParam(ImageReadParam param, boolean copyTagSets) {
    // Create a new TIFFImageReadParam.
    TIFFImageReadParam newParam = new TIFFImageReadParam();

    // Copy the basic settings.
    newParam.setSourceSubsampling(
        param.getSourceXSubsampling(),
        param.getSourceYSubsampling(),
        param.getSubsamplingXOffset(),
        param.getSubsamplingYOffset());
    newParam.setSourceBands(param.getSourceBands());
    newParam.setDestinationBands(param.getDestinationBands());
    newParam.setDestinationOffset(param.getDestinationOffset());

    // Set the decompressor and color converter.
    if (param instanceof TIFFImageReadParam) {
      // Copy the settings from the input parameter.
      TIFFImageReadParam tparam = (TIFFImageReadParam) param;
      newParam.setTIFFDecompressor(tparam.getTIFFDecompressor());
      newParam.setColorConverter(tparam.getColorConverter());

      if (copyTagSets) {
        List tagSets = tparam.getAllowedTagSets();
        if (tagSets != null) {
          Iterator tagSetIter = tagSets.iterator();
          if (tagSetIter != null) {
            while (tagSetIter.hasNext()) {
              TIFFTagSet tagSet = (TIFFTagSet) tagSetIter.next();
              newParam.addAllowedTagSet(tagSet);
            }
          }
        }
      }
    } else {
      // Set the decompressor and color converter to null.
      newParam.setTIFFDecompressor(null);
      newParam.setColorConverter(null);
    }

    return newParam;
  }
  public BufferedImage read(int imageIndex, ImageReadParam param) throws IOException {

    BufferedImage dst = null;
    try {
      // Calculate and return a Rectangle that identifies the region of
      // the
      // source image that should be read:
      //
      // 1. If param is null, the upper-left corner of the region is (0,
      // 0),
      // and the width and height are specified by the width and height
      // arguments. In other words, the entire image is read.
      //
      // 2. If param is not null
      //
      // 2.1 If param.getSourceRegion() returns a non-null Rectangle, the
      // region is calculated as the intersection of param's Rectangle
      // and the earlier (0, 0, width, height Rectangle).
      //
      // 2.2 param.getSubsamplingXOffset() is added to the region's x
      // coordinate and subtracted from its width.
      //
      // 2.3 param.getSubsamplingYOffset() is added to the region's y
      // coordinate and subtracted from its height.

      int width = getWidth(imageIndex);
      int height = getHeight(imageIndex);

      Rectangle sourceRegion = getSourceRegion(param, width, height);

      // Source subsampling is used to return a scaled-down source image.
      // Default 1 values for X and Y subsampling indicate that a
      // non-scaled
      // source image will be returned.

      int sourceXSubsampling = 1;
      int sourceYSubsampling = 1;

      // The destination offset determines the starting location in the
      // destination where decoded pixels are placed. Default (0, 0)
      // values indicate the upper-left corner.

      Point destinationOffset = new Point(0, 0);

      // If param is not null, override the source subsampling, and
      // destination offset defaults.

      if (param != null) {
        sourceXSubsampling = param.getSourceXSubsampling();
        sourceYSubsampling = param.getSourceYSubsampling();
        destinationOffset = param.getDestinationOffset();
      }

      // Obtain a BufferedImage into which decoded pixels will be placed.
      // This destination will be returned to the application.
      //
      // 1. If param is not null
      //
      // 1.1 If param.getDestination() returns a BufferedImage
      //
      // 1.1.1 Return this BufferedImage
      //
      // Else
      //
      // 1.1.2 Invoke param.getDestinationType ().
      //
      // 1.1.3 If the returned ImageTypeSpecifier equals
      // getImageTypes (0) (see below), return its BufferedImage.
      //
      // 2. If param is null or a BufferedImage has not been obtained
      //
      // 2.1 Return getImageTypes (0)'s BufferedImage.

      dst = getDestination(param, getImageTypes(0), width, height);

      // Create a WritableRaster for the destination.

      WritableRaster wrDst = dst.getRaster();

      JBIG2Bitmap bitmap =
          decoder
              .getPageAsJBIG2Bitmap(imageIndex)
              .getSlice(sourceRegion.x, sourceRegion.y, sourceRegion.width, sourceRegion.height);

      BufferedImage image = bitmap.getBufferedImage();

      int newWidth = (int) (image.getWidth() * (1 / (double) sourceXSubsampling));
      int newHeight = (int) (image.getHeight() * (1 / (double) sourceYSubsampling));

      BufferedImage scaledImage = scaleImage(image.getRaster(), newWidth, newHeight, 1, 1);

      Raster raster = null;

      if (scaledImage != null) {
        raster = scaledImage.getRaster();
      } else raster = image.getRaster();

      wrDst.setRect(destinationOffset.x, destinationOffset.y, raster);

    } catch (RuntimeException e) {
      e.printStackTrace();
    }

    return dst;
  }
  public RawRenderedImage(
      RawImageInputStream iis, RawImageReader reader, ImageReadParam param, int imageIndex)
      throws IOException {
    this.iis = iis;
    this.reader = reader;
    this.param = param;
    this.imageIndex = imageIndex;
    this.position = iis.getImageOffset(imageIndex);
    this.originalDimension = iis.getImageDimension(imageIndex);

    ImageTypeSpecifier type = iis.getImageType();
    sampleModel = originalSampleModel = type.getSampleModel();
    colorModel = type.getColorModel();

    // If the destination band is set used it
    sourceBands = (param == null) ? null : param.getSourceBands();

    if (sourceBands == null) {
      nComp = originalSampleModel.getNumBands();
      sourceBands = new int[nComp];
      for (int i = 0; i < nComp; i++) sourceBands[i] = i;
    } else {
      sampleModel = originalSampleModel.createSubsetSampleModel(sourceBands);
      colorModel = ImageUtil.createColorModel(null, sampleModel);
    }

    nComp = sourceBands.length;

    destinationBands = (param == null) ? null : param.getDestinationBands();
    if (destinationBands == null) {
      destinationBands = new int[nComp];
      for (int i = 0; i < nComp; i++) destinationBands[i] = i;
    }

    Dimension dim = iis.getImageDimension(imageIndex);
    this.width = dim.width;
    this.height = dim.height;

    Rectangle sourceRegion = new Rectangle(0, 0, this.width, this.height);

    originalRegion = (Rectangle) sourceRegion.clone();

    destinationRegion = (Rectangle) sourceRegion.clone();

    if (param != null) {
      RawImageReader.computeRegionsWrapper(
          param, this.width, this.height, param.getDestination(), sourceRegion, destinationRegion);
      scaleX = param.getSourceXSubsampling();
      scaleY = param.getSourceYSubsampling();
      xOffset = param.getSubsamplingXOffset();
      yOffset = param.getSubsamplingYOffset();
    }

    sourceOrigin = new Point(sourceRegion.x, sourceRegion.y);
    if (!destinationRegion.equals(sourceRegion)) noTransform = false;

    this.tileDataSize = ImageUtil.getTileSize(originalSampleModel);

    this.tileWidth = originalSampleModel.getWidth();
    this.tileHeight = originalSampleModel.getHeight();
    this.tileGridXOffset = destinationRegion.x;
    this.tileGridYOffset = destinationRegion.y;
    this.originalNumXTiles = getNumXTiles();

    this.width = destinationRegion.width;
    this.height = destinationRegion.height;
    this.minX = destinationRegion.x;
    this.minY = destinationRegion.y;

    sampleModel = sampleModel.createCompatibleSampleModel(tileWidth, tileHeight);

    maxXTile = originalDimension.width / tileWidth;
    maxYTile = originalDimension.height / tileHeight;
  }
Beispiel #24
0
  public BufferedImage read(int imageIndex, ImageReadParam param) throws IOException {
    prepareRead(imageIndex, param);
    this.theImage = getDestination(param, getImageTypes(imageIndex), width, height);

    srcXSubsampling = imageReadParam.getSourceXSubsampling();
    srcYSubsampling = imageReadParam.getSourceYSubsampling();

    Point p = imageReadParam.getDestinationOffset();
    dstXOffset = p.x;
    dstYOffset = p.y;

    // This could probably be made more efficient...
    Rectangle srcRegion = new Rectangle(0, 0, 0, 0);
    Rectangle destRegion = new Rectangle(0, 0, 0, 0);

    computeRegions(imageReadParam, width, height, theImage, srcRegion, destRegion);

    // Initial source pixel, taking source region and source
    // subsamplimg offsets into account
    sourceXOffset = srcRegion.x;
    sourceYOffset = srcRegion.y;

    pixelsToRead = destRegion.width * destRegion.height;
    pixelsRead = 0;

    processImageStarted(imageIndex);
    processImageProgress(0.0f);

    tilesAcross = (width + tileOrStripWidth - 1) / tileOrStripWidth;
    tilesDown = (height + tileOrStripHeight - 1) / tileOrStripHeight;

    int compression = getCompression();

    // Attempt to get decompressor and color converted from the read param

    TIFFColorConverter colorConverter = null;
    if (imageReadParam instanceof TIFFImageReadParam) {
      TIFFImageReadParam tparam = (TIFFImageReadParam) imageReadParam;
      this.decompressor = tparam.getTIFFDecompressor();
      colorConverter = tparam.getColorConverter();
    }

    // If we didn't find one, use a standard decompressor
    if (this.decompressor == null) {
      if (compression == BaselineTIFFTagSet.COMPRESSION_NONE) {
        // Get the fillOrder field.
        TIFFField fillOrderField = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_FILL_ORDER);

        // Set the decompressor based on the fill order.
        if (fillOrderField != null && fillOrderField.getAsInt(0) == 2) {
          this.decompressor = new TIFFLSBDecompressor();
        } else {
          this.decompressor = new TIFFNullDecompressor();
        }
      } else if (compression == BaselineTIFFTagSet.COMPRESSION_CCITT_T_6) {
        this.decompressor = new TIFFFaxDecompressor();
      } else if (compression == BaselineTIFFTagSet.COMPRESSION_CCITT_T_4) {
        this.decompressor = new TIFFFaxDecompressor();
      } else if (compression == BaselineTIFFTagSet.COMPRESSION_CCITT_RLE) {
        this.decompressor = new TIFFFaxDecompressor();
      } else if (compression == BaselineTIFFTagSet.COMPRESSION_PACKBITS) {
        if (DEBUG) {
          System.out.println("Using TIFFPackBitsDecompressor");
        }
        this.decompressor = new TIFFPackBitsDecompressor();
      } else if (compression == BaselineTIFFTagSet.COMPRESSION_LZW) {
        if (DEBUG) {
          System.out.println("Using TIFFLZWDecompressor");
        }
        TIFFField predictorField = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_PREDICTOR);
        int predictor =
            ((predictorField == null)
                ? BaselineTIFFTagSet.PREDICTOR_NONE
                : predictorField.getAsInt(0));
        this.decompressor = new TIFFLZWDecompressor(predictor);
      } else if (compression == BaselineTIFFTagSet.COMPRESSION_JPEG) {
        this.decompressor = new TIFFJPEGDecompressor();
      } else if (compression == BaselineTIFFTagSet.COMPRESSION_ZLIB
          || compression == BaselineTIFFTagSet.COMPRESSION_DEFLATE) {
        TIFFField predictorField = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_PREDICTOR);
        int predictor =
            ((predictorField == null)
                ? BaselineTIFFTagSet.PREDICTOR_NONE
                : predictorField.getAsInt(0));
        this.decompressor = new TIFFDeflateDecompressor(predictor);
      } else if (compression == BaselineTIFFTagSet.COMPRESSION_OLD_JPEG) {
        TIFFField JPEGProcField = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_JPEG_PROC);
        if (JPEGProcField == null) {
          processWarningOccurred(
              "JPEGProc field missing; assuming baseline sequential JPEG process.");
        } else if (JPEGProcField.getAsInt(0) != BaselineTIFFTagSet.JPEG_PROC_BASELINE) {
          throw new IIOException(
              "Old-style JPEG supported for baseline sequential JPEG process only!");
        }
        this.decompressor = new TIFFOldJPEGDecompressor();
        // throw new IIOException("Old-style JPEG not supported!");
      } else {
        throw new IIOException("Unsupported compression type (tag number = " + compression + ")!");
      }

      if (photometricInterpretation == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_Y_CB_CR
          && compression != BaselineTIFFTagSet.COMPRESSION_JPEG
          && compression != BaselineTIFFTagSet.COMPRESSION_OLD_JPEG) {
        boolean convertYCbCrToRGB =
            theImage.getColorModel().getColorSpace().getType() == ColorSpace.TYPE_RGB;
        TIFFDecompressor wrappedDecompressor =
            this.decompressor instanceof TIFFNullDecompressor ? null : this.decompressor;
        this.decompressor = new TIFFYCbCrDecompressor(wrappedDecompressor, convertYCbCrToRGB);
      }
    }

    if (DEBUG) {
      System.out.println("\nDecompressor class = " + decompressor.getClass().getName() + "\n");
    }

    if (colorConverter == null) {
      if (photometricInterpretation == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_CIELAB
          && theImage.getColorModel().getColorSpace().getType() == ColorSpace.TYPE_RGB) {
        colorConverter = new TIFFCIELabColorConverter();
      } else if (photometricInterpretation == BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_Y_CB_CR
          && !(this.decompressor instanceof TIFFYCbCrDecompressor)
          && compression != BaselineTIFFTagSet.COMPRESSION_JPEG
          && compression != BaselineTIFFTagSet.COMPRESSION_OLD_JPEG) {
        colorConverter = new TIFFYCbCrColorConverter(imageMetadata);
      }
    }

    decompressor.setReader(this);
    decompressor.setMetadata(imageMetadata);
    decompressor.setImage(theImage);

    decompressor.setPhotometricInterpretation(photometricInterpretation);
    decompressor.setCompression(compression);
    decompressor.setSamplesPerPixel(samplesPerPixel);
    decompressor.setBitsPerSample(bitsPerSample);
    decompressor.setSampleFormat(sampleFormat);
    decompressor.setExtraSamples(extraSamples);
    decompressor.setColorMap(colorMap);

    decompressor.setColorConverter(colorConverter);

    decompressor.setSourceXOffset(sourceXOffset);
    decompressor.setSourceYOffset(sourceYOffset);
    decompressor.setSubsampleX(srcXSubsampling);
    decompressor.setSubsampleY(srcYSubsampling);

    decompressor.setDstXOffset(dstXOffset);
    decompressor.setDstYOffset(dstYOffset);

    decompressor.setSourceBands(sourceBands);
    decompressor.setDestinationBands(destinationBands);

    // Compute bounds on the tile indices for this source region.
    int minTileX = TIFFImageWriter.XToTileX(srcRegion.x, 0, tileOrStripWidth);
    int minTileY = TIFFImageWriter.YToTileY(srcRegion.y, 0, tileOrStripHeight);
    int maxTileX = TIFFImageWriter.XToTileX(srcRegion.x + srcRegion.width - 1, 0, tileOrStripWidth);
    int maxTileY =
        TIFFImageWriter.YToTileY(srcRegion.y + srcRegion.height - 1, 0, tileOrStripHeight);

    boolean isAbortRequested = false;
    if (planarConfiguration == BaselineTIFFTagSet.PLANAR_CONFIGURATION_PLANAR) {

      decompressor.setPlanar(true);

      int[] sb = new int[1];
      int[] db = new int[1];
      for (int tj = minTileY; tj <= maxTileY; tj++) {
        for (int ti = minTileX; ti <= maxTileX; ti++) {
          for (int band = 0; band < numBands; band++) {
            sb[0] = sourceBands[band];
            decompressor.setSourceBands(sb);
            db[0] = destinationBands[band];
            decompressor.setDestinationBands(db);
            // XXX decompressor.beginDecoding();

            // The method abortRequested() is synchronized
            // so check it only once per loop just before
            // doing any actual decoding.
            if (abortRequested()) {
              isAbortRequested = true;
              break;
            }

            decodeTile(ti, tj, band);
          }

          if (isAbortRequested) break;

          reportProgress();
        }

        if (isAbortRequested) break;
      }
    } else {
      // XXX decompressor.beginDecoding();

      for (int tj = minTileY; tj <= maxTileY; tj++) {
        for (int ti = minTileX; ti <= maxTileX; ti++) {
          // The method abortRequested() is synchronized
          // so check it only once per loop just before
          // doing any actual decoding.
          if (abortRequested()) {
            isAbortRequested = true;
            break;
          }

          decodeTile(ti, tj, -1);

          reportProgress();
        }

        if (isAbortRequested) break;
      }
    }

    if (isAbortRequested) {
      processReadAborted();
    } else {
      processImageComplete();
    }

    return theImage;
  }
  /**
   * Tests the {@link OverviewsController} with support for different resolutions/different number
   * of overviews.
   *
   * <p>world_a.tif => Pixel Size = (0.833333333333333,-0.833333333333333); 4 overviews world_b.tif
   * => Pixel Size = (1.406250000000000,-1.406250000000000); 2 overviews
   *
   * @throws IOException
   * @throws MismatchedDimensionException
   * @throws FactoryException
   * @throws TransformException
   */
  @Test
  public void testHeterogeneousGranules()
      throws IOException, MismatchedDimensionException, FactoryException, TransformException {

    final CoordinateReferenceSystem WGS84 = CRS.decode("EPSG:4326", true);
    final ReferencedEnvelope TEST_BBOX_A = new ReferencedEnvelope(-180, 0, -90, 90, WGS84);
    final ReferencedEnvelope TEST_BBOX_B = new ReferencedEnvelope(0, 180, 0, 90, WGS84);

    URL heterogeneousGranulesURL = TestData.url(this, "heterogeneous");
    // //
    //
    // Initialize mosaic variables
    //
    // //
    final Hints hints = new Hints(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM, WGS84);
    final AbstractGridFormat format =
        (AbstractGridFormat) GridFormatFinder.findFormat(heterogeneousGranulesURL, hints);
    Assert.assertNotNull(format);
    Assert.assertFalse("UknownFormat", format instanceof UnknownFormat);

    final ImageMosaicReader reader =
        (ImageMosaicReader) format.getReader(heterogeneousGranulesURL, hints);
    Assert.assertNotNull(reader);

    final int nOv = reader.getNumberOfOvervies();
    final double[] hRes = reader.getHighestRes();
    final RasterManager rasterManager = new RasterManager(reader);

    // //
    //
    // Initialize granules related variables
    //
    // //
    final File g1File = new File(DataUtilities.urlToFile(heterogeneousGranulesURL), "world_a.tif");
    final File g2File = new File(DataUtilities.urlToFile(heterogeneousGranulesURL), "world_b.tif");
    final ImageReadParam readParamsG1 = new ImageReadParam();
    final ImageReadParam readParamsG2 = new ImageReadParam();
    int imageIndexG1 = 0;
    int imageIndexG2 = 0;

    final GranuleDescriptor granuleDescriptor1 =
        new GranuleDescriptor(g1File.getAbsolutePath(), TEST_BBOX_A, spi, (Geometry) null, true);
    final GranuleDescriptor granuleDescriptor2 =
        new GranuleDescriptor(g2File.getAbsolutePath(), TEST_BBOX_B, spi, (Geometry) null, true);
    assertNotNull(granuleDescriptor1.toString());
    assertNotNull(granuleDescriptor2.toString());

    final OverviewsController ovControllerG1 = granuleDescriptor1.overviewsController;
    final OverviewsController ovControllerG2 = granuleDescriptor2.overviewsController;

    // //
    //
    // Initializing read request
    //
    // //
    final GeneralEnvelope envelope = reader.getOriginalEnvelope();
    final GridEnvelope originalRange = reader.getOriginalGridRange();
    final Rectangle rasterArea =
        new Rectangle(
            0,
            0,
            (int) Math.ceil(originalRange.getSpan(0) / 9.0),
            (int) Math.ceil(originalRange.getSpan(1) / 9.0));
    final GridEnvelope2D range = new GridEnvelope2D(rasterArea);
    final GridToEnvelopeMapper geMapper = new GridToEnvelopeMapper(range, envelope);
    geMapper.setPixelAnchor(PixelInCell.CELL_CENTER);
    final AffineTransform gridToWorld = geMapper.createAffineTransform();
    final double requestedResolution[] =
        new double[] {
          XAffineTransform.getScaleX0(gridToWorld), XAffineTransform.getScaleY0(gridToWorld)
        };

    TestSet at = null;
    if (nOv == 4 && Math.abs(hRes[0] - 0.833333333333) <= THRESHOLD) {
      at = at1;
    } else if (nOv == 2 && Math.abs(hRes[0] - 1.40625) <= THRESHOLD) {
      at = at2;
    } else {
      return;
    }

    // //
    //
    // Starting OverviewsController tests
    //
    // //
    final OverviewPolicy[] ovPolicies =
        new OverviewPolicy[] {
          OverviewPolicy.QUALITY,
          OverviewPolicy.SPEED,
          OverviewPolicy.NEAREST,
          OverviewPolicy.IGNORE
        };
    for (int i = 0; i < ovPolicies.length; i++) {
      OverviewPolicy ovPolicy = ovPolicies[i];
      LOGGER.info("Testing with OverviewPolicy = " + ovPolicy.toString());
      imageIndexG1 =
          ReadParamsController.setReadParams(
              requestedResolution,
              ovPolicy,
              DecimationPolicy.ALLOW,
              readParamsG1,
              rasterManager,
              ovControllerG1);
      imageIndexG2 =
          ReadParamsController.setReadParams(
              requestedResolution,
              ovPolicy,
              DecimationPolicy.ALLOW,
              readParamsG2,
              rasterManager,
              ovControllerG2);
      assertSame(at.ot[i].g1.imageIndex, imageIndexG1);
      assertSame(at.ot[i].g2.imageIndex, imageIndexG2);
      assertSame(at.ot[i].g1.ssx, readParamsG1.getSourceXSubsampling());
      assertSame(at.ot[i].g1.ssy, readParamsG1.getSourceYSubsampling());
      assertSame(at.ot[i].g2.ssx, readParamsG2.getSourceXSubsampling());
      assertSame(at.ot[i].g2.ssy, readParamsG2.getSourceYSubsampling());
    }
  }
  /**
   * This method is responsible for preparing the read param for doing an {@link
   * ImageReader#read(int, ImageReadParam)}.
   *
   * <p>This method is responsible for preparing the read param for doing an {@link
   * ImageReader#read(int, ImageReadParam)}. It sets the passed {@link ImageReadParam} in terms of
   * decimation on reading using the provided requestedEnvelope and requestedDim to evaluate the
   * needed resolution. It also returns and {@link Integer} representing the index of the raster to
   * be read when dealing with multipage raster.
   *
   * @param overviewPolicy it can be one of {@link Hints#VALUE_OVERVIEW_POLICY_IGNORE}, {@link
   *     Hints#VALUE_OVERVIEW_POLICY_NEAREST}, {@link Hints#VALUE_OVERVIEW_POLICY_QUALITY} or {@link
   *     Hints#VALUE_OVERVIEW_POLICY_SPEED}. It specifies the policy to compute the overviews level
   *     upon request.
   * @param readP an instance of {@link ImageReadParam} for setting the subsampling factors.
   * @param requestedEnvelope the {@link GeneralEnvelope} we are requesting.
   * @param requestedDim the requested dimensions.
   * @return the index of the raster to read in the underlying data source.
   * @throws IOException
   * @throws TransformException
   */
  protected Integer setReadParams(
      String coverageName,
      OverviewPolicy overviewPolicy,
      ImageReadParam readP,
      GeneralEnvelope requestedEnvelope,
      Rectangle requestedDim)
      throws IOException, TransformException {

    // //
    //
    // Default image index 0
    //
    // //
    Integer imageChoice = new Integer(0);

    // //
    //
    // Init overview policy
    //
    // //
    // when policy is explictly provided it overrides the policy provided
    // using hints.
    if (overviewPolicy == null) overviewPolicy = extractOverviewPolicy();

    // //
    //
    // default values for subsampling
    //
    // //
    readP.setSourceSubsampling(1, 1, 0, 0);

    // //
    //
    // requested to ignore overviews
    //
    // //
    if (overviewPolicy.equals(OverviewPolicy.IGNORE)) return imageChoice;

    // //
    //
    // Am I going to decimate or to use overviews? If this file has only
    // one page we use decimation, otherwise we use the best page available.
    // Future versions should use both.
    //
    // //
    final boolean useOverviews = (numOverviews > 0) ? true : false;

    // //
    //
    // Resolution requested. I am here computing the resolution required by
    // the user.
    //
    // //
    double[] requestedRes =
        getResolution(requestedEnvelope, requestedDim, getCoordinateReferenceSystem(coverageName));
    if (requestedRes == null) return imageChoice;

    // //
    //
    // overviews or decimation
    //
    // //
    if (useOverviews) imageChoice = pickOverviewLevel(coverageName, overviewPolicy, requestedRes);

    // /////////////////////////////////////////////////////////////////////
    // DECIMATION ON READING
    // /////////////////////////////////////////////////////////////////////
    decimationOnReadingControl(coverageName, imageChoice, readP, requestedRes);
    return imageChoice;
  }
  public BufferedImage read(int pIndex, ImageReadParam pParam) throws IOException {
    try {
      init(pIndex);

      processImageStarted(pIndex);

      // Some more waste of time and space...
      Dimension size = mSize;

      if (pParam != null) {
        // Source region
        // TODO: Maybe have to do some tests, to check if we are within bounds...
        Rectangle sourceRegion = pParam.getSourceRegion();
        if (sourceRegion != null) {
          mImage = mImage.cropImage(sourceRegion);
          size = sourceRegion.getSize();
        }

        // Subsampling
        if (pParam.getSourceXSubsampling() > 1 || pParam.getSourceYSubsampling() > 1) {
          int w = size.width / pParam.getSourceXSubsampling();
          int h = size.height / pParam.getSourceYSubsampling();

          mImage = mImage.sampleImage(w, h);
          size = new Dimension(w, h);
        }
      }

      if (abortRequested()) {
        processReadAborted();
        return ImageUtil.createClear(size.width, size.height, null);
      }

      processImageProgress(10f);
      BufferedImage buffered = MagickUtil.toBuffered(mImage);
      processImageProgress(100f);

      /**/
      // System.out.println("Created image: " + buffered);
      // System.out.println("ColorModel: " + buffered.getColorModel().getClass().getName());
      // if (buffered.getColorModel() instanceof java.awt.image.IndexColorModel) {
      //    java.awt.image.IndexColorModel cm = (java.awt.image.IndexColorModel)
      // buffered.getColorModel();
      //    for (int i = 0; i < cm.getMapSize(); i++) {
      //        System.out.println("0x" + Integer.toHexString(cm.getRGB(i)));
      //    }
      // }
      // */

      /**
       * System.out.println("Colorspace: " + mImage.getColorspace()); System.out.println("Depth: " +
       * mImage.getDepth()); System.out.println("Format: " + mImage.getImageFormat());
       * System.out.println("Type: " + mImage.getImageType()); System.out.println("IPTCProfile: " +
       * StringUtil.deepToString(mImage.getIptcProfile())); System.out.println("StorageClass: " +
       * mImage.getStorageClass()); //
       */
      processImageComplete();

      return buffered;
    } catch (MagickException e) {
      // Wrap in IIOException
      throw new IIOException(e.getMessage(), e);
    }
  }
Beispiel #28
0
  /**
   * Load a specified a raster as a portion of the granule describe by this {@link
   * GranuleDescriptor}.
   *
   * @param imageReadParameters the {@link ImageReadParam} to use for reading.
   * @param index the index to use for the {@link ImageReader}.
   * @param cropBBox the bbox to use for cropping.
   * @param mosaicWorldToGrid the cropping grid to world transform.
   * @param request the incoming request to satisfy.
   * @param hints {@link Hints} to be used for creating this raster.
   * @return a specified a raster as a portion of the granule describe by this {@link
   *     GranuleDescriptor}.
   * @throws IOException in case an error occurs.
   */
  public GranuleLoadingResult loadRaster(
      final ImageReadParam imageReadParameters,
      final int index,
      final ReferencedEnvelope cropBBox,
      final MathTransform2D mosaicWorldToGrid,
      final RasterLayerRequest request,
      final Hints hints)
      throws IOException {

    if (LOGGER.isLoggable(java.util.logging.Level.FINER)) {
      final String name = Thread.currentThread().getName();
      LOGGER.finer(
          "Thread:" + name + " Loading raster data for granuleDescriptor " + this.toString());
    }
    ImageReadParam readParameters = null;
    int imageIndex;
    final ReferencedEnvelope bbox =
        inclusionGeometry != null
            ? new ReferencedEnvelope(
                granuleBBOX.intersection(inclusionGeometry.getEnvelopeInternal()),
                granuleBBOX.getCoordinateReferenceSystem())
            : granuleBBOX;
    boolean doFiltering = false;
    if (filterMe) {
      doFiltering = Utils.areaIsDifferent(inclusionGeometry, baseGridToWorld, granuleBBOX);
    }

    // intersection of this tile bound with the current crop bbox
    final ReferencedEnvelope intersection =
        new ReferencedEnvelope(
            bbox.intersection(cropBBox), cropBBox.getCoordinateReferenceSystem());
    if (intersection.isEmpty()) {
      if (LOGGER.isLoggable(java.util.logging.Level.FINE)) {
        LOGGER.fine(
            new StringBuilder("Got empty intersection for granule ")
                .append(this.toString())
                .append(" with request ")
                .append(request.toString())
                .append(" Resulting in no granule loaded: Empty result")
                .toString());
      }
      return null;
    }

    ImageInputStream inStream = null;
    ImageReader reader = null;
    try {
      //
      // get info about the raster we have to read
      //

      // get a stream
      assert cachedStreamSPI != null : "no cachedStreamSPI available!";
      inStream =
          cachedStreamSPI.createInputStreamInstance(
              granuleUrl, ImageIO.getUseCache(), ImageIO.getCacheDirectory());
      if (inStream == null) return null;

      // get a reader and try to cache the relevant SPI
      if (cachedReaderSPI == null) {
        reader = ImageIOExt.getImageioReader(inStream);
        if (reader != null) cachedReaderSPI = reader.getOriginatingProvider();
      } else reader = cachedReaderSPI.createReaderInstance();
      if (reader == null) {
        if (LOGGER.isLoggable(java.util.logging.Level.WARNING)) {
          LOGGER.warning(
              new StringBuilder("Unable to get s reader for granuleDescriptor ")
                  .append(this.toString())
                  .append(" with request ")
                  .append(request.toString())
                  .append(" Resulting in no granule loaded: Empty result")
                  .toString());
        }
        return null;
      }
      // set input
      reader.setInput(inStream);

      // Checking for heterogeneous granules
      if (request.isHeterogeneousGranules()) {
        // create read parameters
        readParameters = new ImageReadParam();

        // override the overviews controller for the base layer
        imageIndex =
            ReadParamsController.setReadParams(
                request.getRequestedResolution(),
                request.getOverviewPolicy(),
                request.getDecimationPolicy(),
                readParameters,
                request.rasterManager,
                overviewsController);
      } else {
        imageIndex = index;
        readParameters = imageReadParameters;
      }

      // get selected level and base level dimensions
      final GranuleOverviewLevelDescriptor selectedlevel = getLevel(imageIndex, reader);

      // now create the crop grid to world which can be used to decide
      // which source area we need to crop in the selected level taking
      // into account the scale factors imposed by the selection of this
      // level together with the base level grid to world transformation
      AffineTransform2D cropWorldToGrid =
          new AffineTransform2D(selectedlevel.gridToWorldTransformCorner);
      cropWorldToGrid = (AffineTransform2D) cropWorldToGrid.inverse();
      // computing the crop source area which lives into the
      // selected level raster space, NOTICE that at the end we need to
      // take into account the fact that we might also decimate therefore
      // we cannot just use the crop grid to world but we need to correct
      // it.
      final Rectangle sourceArea =
          CRS.transform(cropWorldToGrid, intersection).toRectangle2D().getBounds();
      // gutter
      if (selectedlevel.baseToLevelTransform.isIdentity()) sourceArea.grow(2, 2);
      XRectangle2D.intersect(
          sourceArea,
          selectedlevel.rasterDimensions,
          sourceArea); // make sure roundings don't bother us
      // is it empty??
      if (sourceArea.isEmpty()) {
        if (LOGGER.isLoggable(java.util.logging.Level.FINE)) {
          LOGGER.fine(
              "Got empty area for granuleDescriptor "
                  + this.toString()
                  + " with request "
                  + request.toString()
                  + " Resulting in no granule loaded: Empty result");
        }
        return null;

      } else if (LOGGER.isLoggable(java.util.logging.Level.FINER)) {
        LOGGER.finer(
            "Loading level "
                + imageIndex
                + " with source region: "
                + sourceArea
                + " subsampling: "
                + readParameters.getSourceXSubsampling()
                + ","
                + readParameters.getSourceYSubsampling()
                + " for granule:"
                + granuleUrl);
      }

      // Setting subsampling
      int newSubSamplingFactor = 0;
      final String pluginName = cachedReaderSPI.getPluginClassName();
      if (pluginName != null && pluginName.equals(ImageUtilities.DIRECT_KAKADU_PLUGIN)) {
        final int ssx = readParameters.getSourceXSubsampling();
        final int ssy = readParameters.getSourceYSubsampling();
        newSubSamplingFactor = ImageIOUtilities.getSubSamplingFactor2(ssx, ssy);
        if (newSubSamplingFactor != 0) {
          if (newSubSamplingFactor > maxDecimationFactor && maxDecimationFactor != -1) {
            newSubSamplingFactor = maxDecimationFactor;
          }
          readParameters.setSourceSubsampling(newSubSamplingFactor, newSubSamplingFactor, 0, 0);
        }
      }

      // set the source region
      readParameters.setSourceRegion(sourceArea);
      final RenderedImage raster;
      try {
        // read
        raster =
            request
                .getReadType()
                .read(
                    readParameters,
                    imageIndex,
                    granuleUrl,
                    selectedlevel.rasterDimensions,
                    reader,
                    hints,
                    false);

      } catch (Throwable e) {
        if (LOGGER.isLoggable(java.util.logging.Level.FINE)) {
          LOGGER.log(
              java.util.logging.Level.FINE,
              "Unable to load raster for granuleDescriptor "
                  + this.toString()
                  + " with request "
                  + request.toString()
                  + " Resulting in no granule loaded: Empty result",
              e);
        }
        return null;
      }

      // use fixed source area
      sourceArea.setRect(readParameters.getSourceRegion());

      //
      // setting new coefficients to define a new affineTransformation
      // to be applied to the grid to world transformation
      // -----------------------------------------------------------------------------------
      //
      // With respect to the original envelope, the obtained planarImage
      // needs to be rescaled. The scaling factors are computed as the
      // ratio between the cropped source region sizes and the read
      // image sizes.
      //
      // place it in the mosaic using the coords created above;
      double decimationScaleX = ((1.0 * sourceArea.width) / raster.getWidth());
      double decimationScaleY = ((1.0 * sourceArea.height) / raster.getHeight());
      final AffineTransform decimationScaleTranform =
          XAffineTransform.getScaleInstance(decimationScaleX, decimationScaleY);

      // keep into account translation  to work into the selected level raster space
      final AffineTransform afterDecimationTranslateTranform =
          XAffineTransform.getTranslateInstance(sourceArea.x, sourceArea.y);

      // now we need to go back to the base level raster space
      final AffineTransform backToBaseLevelScaleTransform = selectedlevel.baseToLevelTransform;

      // now create the overall transform
      final AffineTransform finalRaster2Model = new AffineTransform(baseGridToWorld);
      finalRaster2Model.concatenate(CoverageUtilities.CENTER_TO_CORNER);
      final double x = finalRaster2Model.getTranslateX();
      final double y = finalRaster2Model.getTranslateY();

      if (!XAffineTransform.isIdentity(backToBaseLevelScaleTransform, Utils.AFFINE_IDENTITY_EPS))
        finalRaster2Model.concatenate(backToBaseLevelScaleTransform);
      if (!XAffineTransform.isIdentity(afterDecimationTranslateTranform, Utils.AFFINE_IDENTITY_EPS))
        finalRaster2Model.concatenate(afterDecimationTranslateTranform);
      if (!XAffineTransform.isIdentity(decimationScaleTranform, Utils.AFFINE_IDENTITY_EPS))
        finalRaster2Model.concatenate(decimationScaleTranform);

      // keep into account translation factors to place this tile
      finalRaster2Model.preConcatenate((AffineTransform) mosaicWorldToGrid);
      final Interpolation interpolation = request.getInterpolation();
      // paranoiac check to avoid that JAI freaks out when computing its internal layouT on images
      // that are too small
      Rectangle2D finalLayout =
          ImageUtilities.layoutHelper(
              raster,
              (float) finalRaster2Model.getScaleX(),
              (float) finalRaster2Model.getScaleY(),
              (float) finalRaster2Model.getTranslateX(),
              (float) finalRaster2Model.getTranslateY(),
              interpolation);
      if (finalLayout.isEmpty()) {
        if (LOGGER.isLoggable(java.util.logging.Level.INFO))
          LOGGER.info(
              "Unable to create a granuleDescriptor "
                  + this.toString()
                  + " due to jai scale bug creating a null source area");
        return null;
      }
      ROI granuleLoadingShape = null;
      if (granuleROIShape != null) {

        final Point2D translate =
            mosaicWorldToGrid.transform(new DirectPosition2D(x, y), (Point2D) null);
        AffineTransform tx2 = new AffineTransform();
        tx2.preConcatenate(
            AffineTransform.getScaleInstance(
                ((AffineTransform) mosaicWorldToGrid).getScaleX(),
                -((AffineTransform) mosaicWorldToGrid).getScaleY()));
        tx2.preConcatenate(
            AffineTransform.getScaleInstance(
                ((AffineTransform) baseGridToWorld).getScaleX(),
                -((AffineTransform) baseGridToWorld).getScaleY()));
        tx2.preConcatenate(
            AffineTransform.getTranslateInstance(translate.getX(), translate.getY()));
        granuleLoadingShape = (ROI) granuleROIShape.transform(tx2);
      }
      // apply the affine transform  conserving indexed color model
      final RenderingHints localHints =
          new RenderingHints(
              JAI.KEY_REPLACE_INDEX_COLOR_MODEL,
              interpolation instanceof InterpolationNearest ? Boolean.FALSE : Boolean.TRUE);
      if (XAffineTransform.isIdentity(finalRaster2Model, Utils.AFFINE_IDENTITY_EPS)) {
        return new GranuleLoadingResult(raster, granuleLoadingShape, granuleUrl, doFiltering);
      } else {
        //
        // In case we are asked to use certain tile dimensions we tile
        // also at this stage in case the read type is Direct since
        // buffered images comes up untiled and this can affect the
        // performances of the subsequent affine operation.
        //
        final Dimension tileDimensions = request.getTileDimensions();
        if (tileDimensions != null && request.getReadType().equals(ReadType.DIRECT_READ)) {
          final ImageLayout layout = new ImageLayout();
          layout.setTileHeight(tileDimensions.width).setTileWidth(tileDimensions.height);
          localHints.add(new RenderingHints(JAI.KEY_IMAGE_LAYOUT, layout));
        } else {
          if (hints != null && hints.containsKey(JAI.KEY_IMAGE_LAYOUT)) {
            final Object layout = hints.get(JAI.KEY_IMAGE_LAYOUT);
            if (layout != null && layout instanceof ImageLayout) {
              localHints.add(
                  new RenderingHints(JAI.KEY_IMAGE_LAYOUT, ((ImageLayout) layout).clone()));
            }
          }
        }
        if (hints != null && hints.containsKey(JAI.KEY_TILE_CACHE)) {
          final Object cache = hints.get(JAI.KEY_TILE_CACHE);
          if (cache != null && cache instanceof TileCache)
            localHints.add(new RenderingHints(JAI.KEY_TILE_CACHE, (TileCache) cache));
        }
        if (hints != null && hints.containsKey(JAI.KEY_TILE_SCHEDULER)) {
          final Object scheduler = hints.get(JAI.KEY_TILE_SCHEDULER);
          if (scheduler != null && scheduler instanceof TileScheduler)
            localHints.add(new RenderingHints(JAI.KEY_TILE_SCHEDULER, (TileScheduler) scheduler));
        }
        boolean addBorderExtender = true;
        if (hints != null && hints.containsKey(JAI.KEY_BORDER_EXTENDER)) {
          final Object extender = hints.get(JAI.KEY_BORDER_EXTENDER);
          if (extender != null && extender instanceof BorderExtender) {
            localHints.add(new RenderingHints(JAI.KEY_BORDER_EXTENDER, (BorderExtender) extender));
            addBorderExtender = false;
          }
        }
        // border extender
        if (addBorderExtender) {
          localHints.add(ImageUtilities.BORDER_EXTENDER_HINTS);
        }
        //                boolean hasScaleX=!(Math.abs(finalRaster2Model.getScaleX()-1) <
        // 1E-2/(raster.getWidth()+1-raster.getMinX()));
        //                boolean hasScaleY=!(Math.abs(finalRaster2Model.getScaleY()-1) <
        // 1E-2/(raster.getHeight()+1-raster.getMinY()));
        //                boolean hasShearX=!(finalRaster2Model.getShearX() == 0.0);
        //                boolean hasShearY=!(finalRaster2Model.getShearY() == 0.0);
        //                boolean hasTranslateX=!(Math.abs(finalRaster2Model.getTranslateX()) <
        // 0.01F);
        //                boolean hasTranslateY=!(Math.abs(finalRaster2Model.getTranslateY()) <
        // 0.01F);
        //                boolean isTranslateXInt=!(Math.abs(finalRaster2Model.getTranslateX() -
        // (int) finalRaster2Model.getTranslateX()) <  0.01F);
        //                boolean isTranslateYInt=!(Math.abs(finalRaster2Model.getTranslateY() -
        // (int) finalRaster2Model.getTranslateY()) <  0.01F);
        //
        //                boolean isIdentity = finalRaster2Model.isIdentity() &&
        // !hasScaleX&&!hasScaleY &&!hasTranslateX&&!hasTranslateY;

        //                // TODO how can we check that the a skew is harmelss????
        //                if(isIdentity){
        //                    // TODO check if we are missing anything like tiling or such that
        // comes from hints
        //                    return new GranuleLoadingResult(raster, granuleLoadingShape,
        // granuleUrl, doFiltering);
        //                }
        //
        //                // TOLERANCE ON PIXELS SIZE
        //
        //                // Check and see if the affine transform is in fact doing
        //                // a Translate operation. That is a scale by 1 and no rotation.
        //                // In which case call translate. Note that only integer translate
        //                // is applicable. For non-integer translate we'll have to do the
        //                // affine.
        //                // If the hints contain an ImageLayout hint, we can't use
        //                // TranslateIntOpImage since it isn't capable of dealing with that.
        //                // Get ImageLayout from renderHints if any.
        //                ImageLayout layout = RIFUtil.getImageLayoutHint(localHints);
        //                if ( !hasScaleX &&
        //                     !hasScaleY  &&
        //                      !hasShearX&&
        //                      !hasShearY&&
        //                      isTranslateXInt&&
        //                      isTranslateYInt&&
        //                    layout == null) {
        //                    // It's a integer translate
        //                    return new GranuleLoadingResult(new TranslateIntOpImage(raster,
        //                                                    localHints,
        //                                                   (int) finalRaster2Model.getShearX(),
        //                                                   (int)
        // finalRaster2Model.getShearY()),granuleLoadingShape, granuleUrl, doFiltering);
        //                }

        ImageWorker iw = new ImageWorker(raster);
        iw.setRenderingHints(localHints);
        iw.affine(finalRaster2Model, interpolation, request.getBackgroundValues());
        return new GranuleLoadingResult(
            iw.getRenderedImage(), granuleLoadingShape, granuleUrl, doFiltering);
      }

    } catch (IllegalStateException e) {
      if (LOGGER.isLoggable(java.util.logging.Level.WARNING)) {
        LOGGER.log(
            java.util.logging.Level.WARNING,
            new StringBuilder("Unable to load raster for granuleDescriptor ")
                .append(this.toString())
                .append(" with request ")
                .append(request.toString())
                .append(" Resulting in no granule loaded: Empty result")
                .toString(),
            e);
      }
      return null;
    } catch (org.opengis.referencing.operation.NoninvertibleTransformException e) {
      if (LOGGER.isLoggable(java.util.logging.Level.WARNING)) {
        LOGGER.log(
            java.util.logging.Level.WARNING,
            new StringBuilder("Unable to load raster for granuleDescriptor ")
                .append(this.toString())
                .append(" with request ")
                .append(request.toString())
                .append(" Resulting in no granule loaded: Empty result")
                .toString(),
            e);
      }
      return null;
    } catch (TransformException e) {
      if (LOGGER.isLoggable(java.util.logging.Level.WARNING)) {
        LOGGER.log(
            java.util.logging.Level.WARNING,
            new StringBuilder("Unable to load raster for granuleDescriptor ")
                .append(this.toString())
                .append(" with request ")
                .append(request.toString())
                .append(" Resulting in no granule loaded: Empty result")
                .toString(),
            e);
      }
      return null;

    } finally {
      try {
        if (request.getReadType() != ReadType.JAI_IMAGEREAD && inStream != null) {
          inStream.close();
        }
      } finally {
        if (request.getReadType() != ReadType.JAI_IMAGEREAD && reader != null) {
          reader.dispose();
        }
      }
    }
  }
Beispiel #29
0
  public BufferedImage read(int imageIndex, ImageReadParam param) throws IOException {
    checkIndex(imageIndex);
    readHeader();

    if (iis == null) throw new IllegalStateException("input is null");

    BufferedImage img;

    clearAbortRequest();
    processImageStarted(imageIndex);

    if (param == null) param = getDefaultReadParam();

    sourceRegion = new Rectangle(0, 0, 0, 0);
    destinationRegion = new Rectangle(0, 0, 0, 0);

    computeRegions(
        param, this.width, this.height, param.getDestination(), sourceRegion, destinationRegion);

    scaleX = param.getSourceXSubsampling();
    scaleY = param.getSourceYSubsampling();

    // If the destination band is set used it
    sourceBands = param.getSourceBands();
    destBands = param.getDestinationBands();

    seleBand = (sourceBands != null) && (destBands != null);
    noTransform = destinationRegion.equals(new Rectangle(0, 0, width, height)) || seleBand;

    if (!seleBand) {
      sourceBands = new int[colorPlanes];
      destBands = new int[colorPlanes];
      for (int i = 0; i < colorPlanes; i++) destBands[i] = sourceBands[i] = i;
    }

    // If the destination is provided, then use it.  Otherwise, create new one
    bi = param.getDestination();

    // Get the image data.
    WritableRaster raster = null;

    if (bi == null) {
      if (sampleModel != null && colorModel != null) {
        sampleModel =
            sampleModel.createCompatibleSampleModel(
                destinationRegion.width + destinationRegion.x,
                destinationRegion.height + destinationRegion.y);
        if (seleBand) sampleModel = sampleModel.createSubsetSampleModel(sourceBands);
        raster = Raster.createWritableRaster(sampleModel, new Point(0, 0));
        bi = new BufferedImage(colorModel, raster, false, null);
      }
    } else {
      raster = bi.getWritableTile(0, 0);
      sampleModel = bi.getSampleModel();
      colorModel = bi.getColorModel();

      noTransform &= destinationRegion.equals(raster.getBounds());
    }

    byte bdata[] = null; // buffer for byte data

    if (sampleModel.getDataType() == DataBuffer.TYPE_BYTE)
      bdata = (byte[]) ((DataBufferByte) raster.getDataBuffer()).getData();

    readImage(bdata);

    if (abortRequested()) processReadAborted();
    else processImageComplete();

    return bi;
  }
Beispiel #30
0
  /**
   * 根据指定坐标和长宽裁剪图片
   *
   * @param inputFilePath 源图片
   * @param outputFilePath 产生新图片路径
   * @param x x轴的开始坐标
   * @param y y轴的开始坐标
   * @param width 所裁剪的宽度
   * @param height 所裁剪的高度
   */
  public static void cut(
      String inputFilePath, String outputFilePath, int x, int y, int width, int height) {

    FileInputStream fileInputStream = null;
    ImageInputStream imageInputStream = null;
    try {
      // 获得源文件
      File inputFile = new File(inputFilePath);
      if (!inputFile.exists()) {
        logger.fatal(new FileNotFoundException());
        return;
      }

      // 读取图片文件
      fileInputStream = new FileInputStream(inputFilePath);

      String format = FileUtil.getFileSuffix(inputFilePath);
      // System.out.println(format);
      // ImageReader声称能够解码指定格式
      Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName(format);
      ImageReader reader = it.next();

      // 获取图片流
      imageInputStream = ImageIO.createImageInputStream(fileInputStream);

      // 输入源中的图像将只按顺序读取
      reader.setInput(imageInputStream, true);

      // 描述如何对流进行解码
      ImageReadParam param = reader.getDefaultReadParam();

      // 图片裁剪区域
      Rectangle rect = new Rectangle(x, y, width, height);

      // 提供一个 BufferedImage,将其用作解码像素数据的目标
      param.setSourceRegion(rect);

      // 使用所提供的 ImageReadParam 读取通过索引 imageIndex 指定的对象
      BufferedImage bi = reader.read(0, param);

      // 保存新图片
      // File tempOutFile = new File(outputFilePath);
      // if (!tempOutFile.exists()) {
      // tempOutFile.mkdirs();
      // }
      ImageIO.write(bi, format, new File(outputFilePath));
    } catch (Exception e) {
      e.printStackTrace();
      logger.fatal(e);
    } finally {
      try {
        if (fileInputStream != null) {
          fileInputStream.close();
        }
        if (imageInputStream != null) {
          imageInputStream.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
        logger.fatal(e);
      }
    }
  }