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; } }