Exemple #1
0
  /**
   * Scale an image up/down to the desired width and height, while maintaining the image's aspect
   * ratio (if requested).
   *
   * @param image the source image to scale
   * @param scaleWidth the new width to scale to
   * @param scaleHeight the new height to scale to
   * @param keepAspect true if the aspect ratio should be maintained.
   * @param color the color to fill borders when maintaining aspect ratio (0 = black, 255 = white).
   * @return a scaled image as RenderedOp
   * @see #scaleImage(RenderedOp, int, int)
   */
  public static RenderedOp scaleImage(
      RenderedOp image, int scaleWidth, int scaleHeight, boolean keepAspect, double color) {
    float xScale = (float) scaleWidth / (float) image.getWidth();
    float yScale = (float) scaleHeight / (float) image.getHeight();
    boolean resize = false;

    if (keepAspect) {
      resize = Math.abs(xScale - yScale) < .0000001;
      xScale = Math.min(xScale, yScale);
      yScale = xScale;
    }

    ParameterBlock params = new ParameterBlock();
    params.addSource(image);

    params.add(xScale); // x scale factor
    params.add(yScale); // y scale factor
    params.add(0.0F); // x translate
    params.add(0.0F); // y translate
    params.add(Interpolation.getInstance(Interpolation.INTERP_BICUBIC));

    RenderedOp result = JAI.create("scale", params, ImageToolkit.NOCACHE_HINT); // $NON-NLS-1$
    if (resize) {
      result = resizeImage(result, scaleWidth, scaleHeight, color);
    }

    return result;
  }
 private RenderedOp createScaledImage(
     RenderedImage sourceImage, S2Resolution resolution, int level) {
   int sourceWidth = sourceImage.getWidth();
   int sourceHeight = sourceImage.getHeight();
   int targetWidth = imageLayouts[0].width >> level;
   int targetHeight = imageLayouts[0].height >> level;
   float scaleX = (float) targetWidth / (float) sourceWidth;
   float scaleY = (float) targetHeight / (float) sourceHeight;
   float corrFactorX = resolution == S2Resolution.R20M ? R20M_X_FACTOR : R60M_X_FACTOR;
   float corrFactorY = resolution == S2Resolution.R20M ? R20M_Y_FACTOR : R60M_Y_FACTOR;
   final Dimension tileDim = getTileDim(targetWidth, targetHeight);
   ImageLayout imageLayout = new ImageLayout();
   imageLayout.setTileWidth(tileDim.width);
   imageLayout.setTileHeight(tileDim.height);
   RenderingHints renderingHints =
       new RenderingHints(
           JAI.KEY_BORDER_EXTENDER, BorderExtender.createInstance(BorderExtender.BORDER_ZERO));
   renderingHints.put(JAI.KEY_IMAGE_LAYOUT, imageLayout);
   RenderedOp scaledImage =
       ScaleDescriptor.create(
           sourceImage,
           scaleX * corrFactorX,
           scaleY * corrFactorY,
           0F,
           0F,
           Interpolation.getInstance(Interpolation.INTERP_NEAREST),
           renderingHints);
   if (scaledImage.getWidth() != targetWidth || scaledImage.getHeight() != targetHeight) {
     return CropDescriptor.create(
         scaledImage, 0.0F, 0.0F, (float) targetWidth, (float) targetHeight, null);
   } else {
     return scaledImage;
   }
 }
Exemple #3
0
  protected RenderedOp resizeJAI(
      int thumbWidth, int thumbHeight, RenderedOp image, boolean scaleComputed) {
    double scale = 1.0;
    if (!scaleComputed) {
      int imageWidth = image.getWidth();
      int imageHeight = image.getHeight();

      scale = computeEvenResizeScale(thumbWidth, thumbHeight, imageWidth, imageHeight);
    }

    RenderingHints qualityHints =
        new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    return JAI.create("SubsampleAverage", image, scale, scale, qualityHints);
  }
Exemple #4
0
  /**
   * Crop down an image to smaller dimensions. Used by resizeImage() when an image dimension is
   * smaller.
   *
   * @param image the source image to crop
   * @param toWidth the new width to crop to
   * @param toHeight the new height to crop to
   * @return a cropped image as RenderedOp
   * @see #resizeImage(RenderedOp, int, int)
   */
  public static RenderedOp cropImage(RenderedOp image, int toWidth, int toHeight) {
    int width = image.getWidth();
    int height = image.getHeight();
    int xOffset = (width - toWidth) / 2;
    int yOffset = (height - toHeight) / 2;
    ParameterBlock params = new ParameterBlock();
    params.addSource(image);

    params.add((float) xOffset); // x origin
    params.add((float) yOffset); // y origin
    params.add((float) toWidth); // width
    params.add((float) toHeight); // height

    return JAI.create("crop", params, null); // $NON-NLS-1$
  }
Exemple #5
0
  /**
   * Resize an image to the new dimensions - no scaling is performed on the image, but the canvas
   * size is changed. Any empty areas are filled with white.
   *
   * @param image the source image to resize
   * @param toWidth the new width to resize to
   * @param toHeight the new height to resize to
   * @param color the color to fill borders when resizing up.
   * @return the resized image as RenderedOp
   */
  public static RenderedOp resizeImage(RenderedOp image, int toWidth, int toHeight, double color) {
    int width = image.getWidth();
    int height = image.getHeight();

    if (width > toWidth || height > toHeight) {
      image = cropImage(image, Math.min(width, toWidth), Math.min(height, toHeight));
    }

    if (width < toWidth || height < toHeight) {
      int w = Math.max((toWidth - width) / 2, 0);
      int h = Math.max((toHeight - height) / 2, 0);

      image = borderImage(image, w, w, h, h, color);
    }

    return image;
  }
  /**
   * This method downscales a band by a given factor
   *
   * @param inputBand - the input band
   * @param scalingFactor - the scaling factor
   * @return Band - the downscaled band
   */
  public static Band downscaleBand(Band inputBand, float scalingFactor) {
    final RenderedImage sourceImage = inputBand.getSourceImage();
    final RenderedOp downscaledImage =
        ScaleDescriptor.create(
            sourceImage,
            1.0f / scalingFactor,
            1.0f / scalingFactor,
            0.0f,
            0.0f,
            Interpolation.getInstance(Interpolation.INTERP_NEAREST),
            null);
    Band downscaledBand =
        new Band(
            inputBand.getName(), inputBand.getDataType(),
            downscaledImage.getWidth(), downscaledImage.getHeight());

    downscaledBand.setSourceImage(downscaledImage);
    return downscaledBand;
  }
  private static BufferedImage convolveICOL(
      RenderedOp source, KernelJAI gaussKernel, KernelJAI distKernel) {
    final int m = gaussKernel.getWidth();
    final int n = m / 2 + 1;

    float[] weights = new float[n];
    float wSum = 0;
    for (int k = 0; k < n; k++) {
      weights[k] = gaussKernel.getElement(distKernel.getXOrigin() + k, distKernel.getYOrigin());
      wSum += weights[k];
    }
    for (int k = 0; k < n; k++) {
      weights[k] /= wSum;
    }

    dumpArray("Weights", weights);

    int width = source.getWidth();
    int height = source.getHeight();
    Raster aRaster = source.getData(new Rectangle(0, 0, width, height));
    BufferedImage cImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
    byte[] aData = ((DataBufferByte) aRaster.getDataBuffer()).getData();
    byte[] cData = ((DataBufferByte) cImage.getRaster().getDataBuffer()).getData();
    for (int y = 0; y < height; y++) {
      for (int x = 0; x < width; x++) {
        float[] sums = new float[n];
        int[] counts = new int[n];
        for (int j = 0; j < m; j++) {
          for (int i = 0; i < m; i++) {
            int k = (int) distKernel.getElement(i, j);
            if (k > 0) {
              int xx = x + i - distKernel.getXOrigin();
              int yy = y + j - distKernel.getYOrigin();
              if (xx >= 0 && xx < width && yy >= 0 && yy < height) {
                int a = (aData[yy * width + xx] & 0xff);
                if (a > 0) { // = if (not no-data)
                  sums[k] += a;
                  counts[k]++;
                }
              }
            }
          }
        }

        int a = aData[y * width + x] & 0xff;

        float c = weights[0] * a;
        for (int k = 1; k < n; k++) {
          if (counts[k] > 0) {
            c += (weights[k] * sums[k]) / counts[k];
          }
        }

        if (a == 0) {
          cData[y * width + x] = (byte) c;
        } else {
          cData[y * width + x] = aData[y * width + x];
        }
      }
    }
    return cImage;
  }
  private void testType(RenderedImage src, boolean nodataUsed, boolean roiUsed) {
    // Optional No Data Range used
    Range noData;
    // Source image data type
    int dataType = src.getSampleModel().getDataType();
    // If no Data are present, the No Data Range associated is used
    if (nodataUsed) {

      switch (dataType) {
        case DataBuffer.TYPE_BYTE:
          noData = noDataByte;
          break;
        case DataBuffer.TYPE_USHORT:
          noData = noDataUShort;
          break;
        case DataBuffer.TYPE_SHORT:
          noData = noDataShort;
          break;
        case DataBuffer.TYPE_INT:
          noData = noDataInt;
          break;
        case DataBuffer.TYPE_FLOAT:
          noData = noDataFloat;
          break;
        case DataBuffer.TYPE_DOUBLE:
          noData = noDataDouble;
          break;
        default:
          throw new IllegalArgumentException("Wrong data type");
      }
    } else {
      noData = null;
    }

    ROI roi;

    if (roiUsed) {
      roi = roiObject;
    } else {
      roi = null;
    }

    // BandCombined result
    RenderedOp combined =
        BandCombineDescriptor.create(src, matrix, roi, noData, destinationNoData, null);

    int tileWidth = combined.getTileWidth();
    int tileHeight = combined.getTileHeight();
    int minTileX = combined.getMinTileX();
    int minTileY = combined.getMinTileY();
    int numXTiles = combined.getNumXTiles();
    int numYTiles = combined.getNumYTiles();
    int maxTileX = minTileX + numXTiles;
    int maxTileY = minTileY + numYTiles;
    // Ensure same size
    assertEquals(combined.getWidth(), src.getWidth());
    assertEquals(combined.getHeight(), src.getHeight());
    assertEquals(combined.getMinX(), src.getMinX());
    assertEquals(combined.getMinY(), src.getMinY());
    assertEquals(minTileX, src.getMinTileX());
    assertEquals(minTileY, src.getMinTileY());
    assertEquals(numXTiles, src.getNumXTiles());
    assertEquals(numYTiles, src.getNumYTiles());
    assertEquals(tileWidth, src.getTileWidth());
    assertEquals(tileHeight, src.getTileHeight());

    int srcBands = src.getSampleModel().getNumBands();
    int dstBands = combined.getNumBands();

    // Ensure a correct band size
    assertEquals(dstBands, matrix.length);

    // Check on all the pixels if they have been calculate correctly
    for (int tileX = minTileX; tileX < maxTileX; tileX++) {
      for (int tileY = minTileY; tileY < maxTileY; tileY++) {
        Raster tile = combined.getTile(tileX, tileY);
        Raster srcTile = src.getTile(tileX, tileY);

        int minX = tile.getMinX();
        int minY = tile.getMinY();
        int maxX = minX + tileWidth - 1;
        int maxY = minY + tileHeight - 1;

        for (int x = minX; x <= maxX; x++) {
          for (int y = minY; y <= maxY; y++) {

            boolean isValidRoi = !roiUsed || (roiUsed && roiObject.contains(x, y));

            if (isValidRoi) {
              for (int b = 0; b < dstBands; b++) {
                // Getting the result
                double result = tile.getSampleDouble(x, y, b);

                // Calculating the expected result from sources
                boolean valid = false;
                double calculated = 0;

                for (int i = 0; i < srcBands; i++) {
                  double sample = srcTile.getSampleDouble(x, y, i);
                  boolean isValidData =
                      !nodataUsed || (nodataUsed && !noDataDouble.contains(sample));
                  valid |= isValidData;
                  if (isValidData) {
                    switch (dataType) {
                      case DataBuffer.TYPE_BYTE:
                        calculated += ((int) sample & 0xFF) * matrix[b][i];
                        break;
                      case DataBuffer.TYPE_USHORT:
                        calculated += ((int) sample & 0xFFFF) * matrix[b][i];
                        break;
                      case DataBuffer.TYPE_SHORT:
                      case DataBuffer.TYPE_INT:
                      case DataBuffer.TYPE_FLOAT:
                      case DataBuffer.TYPE_DOUBLE:
                        calculated += sample * matrix[b][i];
                        break;
                      default:
                        break;
                    }
                  }
                }

                if (valid) {
                  calculated += matrix[b][srcBands];
                  switch (dataType) {
                    case DataBuffer.TYPE_BYTE:
                      calculated = ImageUtil.clampRoundByte(calculated);
                      result = ImageUtil.clampRoundByte(result);
                      break;
                    case DataBuffer.TYPE_USHORT:
                      calculated = ImageUtil.clampRoundUShort(calculated);
                      result = ImageUtil.clampRoundUShort(result);
                      break;
                    case DataBuffer.TYPE_SHORT:
                      calculated = ImageUtil.clampRoundShort(calculated);
                      result = ImageUtil.clampRoundShort(result);
                      break;
                    case DataBuffer.TYPE_INT:
                      calculated = ImageUtil.clampRoundInt(calculated);
                      result = ImageUtil.clampRoundInt(result);
                      break;
                    case DataBuffer.TYPE_FLOAT:
                      calculated = (float) calculated;
                      calculated = (float) result;
                      break;
                    case DataBuffer.TYPE_DOUBLE:
                      break;
                    default:
                      break;
                  }
                  assertEquals(result, calculated, TOLERANCE);
                } else {
                  assertEquals(result, destNoData, TOLERANCE);
                }
              }
            } else {
              for (int b = 0; b < dstBands; b++) {
                assertEquals(tile.getSampleDouble(x, y, b), destNoData, TOLERANCE);
              }
            }
          }
        }
      }
    }

    // Disposal of the output image
    combined.dispose();
  }