+ *
2. + *
3. Compute statistics on sample values (if needed).
4. + *
5. Reproject the image (if needed).
6. + *

* - * @param source the image to recolor (may be {@code null}). - * @param deviations multiple of standard deviations around the mean, of {@link Double#POSITIVE_INFINITY} - * for not using standard deviation for narrowing the range of values. - * Some values giving good results for a Gaussian distribution are 1.5, 2 or 3. + *

The range of values for the color ramp can be narrowed with following modifiers + * (a {@link Map} is used for allowing addition of more modifiers in future Apache SIS versions). + * All unrecognized modifiers are silently ignored. If no modifier is specified, then the color ramp + * will be stretched from minimum to maximum values.

+ * + * + * + * + * + * + * + * + * + * + * + * + *
Value range modifiers
KeyPurposeExamples
{@code MultStdDev}Multiple of the standard deviation.1.5, 2 or 3.
+ * + * @param source the image to recolor (may be {@code null}). + * @param modifiers modifiers for narrowing the range of values, or {@code null} if none. * @return the image with color ramp stretched between the automatic bounds, * or {@code image} unchanged if the operation can not be applied on the given image. */ - public RenderedImage automaticColorRamp(final RenderedImage source, double deviations) { - ArgumentChecks.ensureStrictlyPositive("deviations", deviations); + public RenderedImage stretchColorRamp(final RenderedImage source, final Map modifiers) { + double deviations = Double.POSITIVE_INFINITY; + if (modifiers != null) { + Number value = modifiers.get("MultStdDev"); + if (value != null) { + deviations = value.doubleValue(); + ArgumentChecks.ensureStrictlyPositive("MultStdDev", deviations); + } + } final int visibleBand = ImageUtilities.getVisibleBand(source); if (visibleBand >= 0) { - final Statistics[] statistics = statistics(source); + final Statistics[] statistics = getStatistics(source); if (statistics != null && visibleBand < statistics.length) { final Statistics s = statistics[visibleBand]; if (s != null) { diff --git a/core/sis-feature/src/main/java/org/apache/sis/image/PlanarImage.java b/core/sis-feature/src/main/java/org/apache/sis/image/PlanarImage.java index 254db3b..ceab89d 100644 --- a/core/sis-feature/src/main/java/org/apache/sis/image/PlanarImage.java +++ b/core/sis-feature/src/main/java/org/apache/sis/image/PlanarImage.java @@ -109,13 +109,30 @@ public abstract class PlanarImage implements RenderedImage { * Key of a property defining the resolutions of sample values in each band. This property is recommended * for images having sample values as floating point numbers. For example if sample values were computed by * value = integer × scale factor, then the resolution is the scale factor. - * This information is used for choosing the number of fraction digits to show when writing sample values in - * text format. + * This information can be used for choosing the number of fraction digits to show when writing sample values + * in text format. * *

Values should be instances of {@code float[]} or {@code double[]}. - * The array length should be the number of bands.

+ * The array length should be the number of bands. This property may be computed automatically during + * {@linkplain org.apache.sis.coverage.grid.GridCoverage#forConvertedValues(boolean) conversions from + * integer values to floating point values}.

*/ - public static final String SAMPLE_RESOLUTIONS_KEY = "SampleResolution"; + public static final String SAMPLE_RESOLUTIONS_KEY = "org.apache.sis.SampleResolution"; + + /** + * Key of property providing statistics on sample values in each band. Providing a value for this key + * is recommended when those statistics are known in advance (for example if they are provided in some + * metadata of a raster format). Statistics are useful for stretching a color palette over the values + * actually used in an image. + * + *

Values should be instances of `{@linkplain org.apache.sis.math.Statistics}[]`. + * The array length should be the number of bands. If this property is not provided, Apache SIS + * may have to {@linkplain ImageProcessor#statistics(RenderedImage) compute statistics itself} + * (by iterating over pixel values) when needed.

+ * + * @see ImageProcessor#statistics(RenderedImage) + */ + public static final String STATISTICS_KEY = "org.apache.sis.Statistics"; /** * Creates a new rendered image. @@ -140,16 +157,18 @@ public abstract class PlanarImage implements RenderedImage { } /** - * Gets a property from this image. - * The property to get is identified by the specified key. Some keys supported by Apache SIS are: + * Gets a property from this image. The property to get is identified by the specified key. + * The set of available keys is given by {@link #getPropertyNames()} and depends on the image instance. + * The following table gives examples of keys recognized by some Apache SIS {@link RenderedImage} instances: * * - * + * * * + * *
Recognized property keysExamples of property keys
Keys Values
{@value #SAMPLE_RESOLUTIONS_KEY} Resolutions of sample values in each band.
{@value #STATISTICS_KEY} Minimum, maximum and mean values for each band.
* - * This method returns {@link Image#UndefinedProperty} if the specified property is not defined. + * This method shall return {@link Image#UndefinedProperty} if the specified property is not defined. * The default implementation returns {@link Image#UndefinedProperty} in all cases. * * @param key the name of the property to get. diff --git a/core/sis-feature/src/main/java/org/apache/sis/image/ResampledImage.java b/core/sis-feature/src/main/java/org/apache/sis/image/ResampledImage.java index 98eeffc..6418239 100644 --- a/core/sis-feature/src/main/java/org/apache/sis/image/ResampledImage.java +++ b/core/sis-feature/src/main/java/org/apache/sis/image/ResampledImage.java @@ -16,8 +16,10 @@ */ package org.apache.sis.image; +import java.util.Set; import java.util.Arrays; import java.util.Objects; +import java.util.Collections; import java.nio.DoubleBuffer; import java.awt.Dimension; import java.awt.Rectangle; @@ -33,6 +35,7 @@ import org.apache.sis.referencing.operation.transform.MathTransforms; import org.apache.sis.internal.coverage.j2d.ImageLayout; import org.apache.sis.internal.coverage.j2d.ImageUtilities; import org.apache.sis.internal.system.Modules; +import org.apache.sis.util.ArraysExt; import org.apache.sis.util.ArgumentChecks; import org.apache.sis.util.logging.Logging; import org.apache.sis.util.resources.Errors; @@ -69,6 +72,14 @@ import org.apache.sis.measure.NumberRange; */ public class ResampledImage extends ComputedImage { /** + * The properties to forwards to source image in calls to {@link #getProperty(String)}. + * This list may be augmented in any future Apache SIS version. + * + * @see #getProperty(String) + */ + private static final Set FILTERED_PROPERTIES = Collections.singleton(SAMPLE_RESOLUTIONS_KEY); + + /** * The {@value} value for identifying code expecting exactly 2 dimensions. */ private static final int BIDIMENSIONAL = 2; @@ -233,7 +244,7 @@ public class ResampledImage extends ComputedImage { if (error == null && toSource instanceof MathTransform2D) try { final Rectangle bounds = getBounds(); final Rectangle2D tb = Shapes2D.transform((MathTransform2D) toSource, bounds, bounds); - if (!ImageUtilities.getBounds(getSource(0)).intersects(tb)) { + if (!ImageUtilities.getBounds(getSource()).intersects(tb)) { return "toSource"; } } catch (TransformException e) { @@ -244,13 +255,65 @@ public class ResampledImage extends ComputedImage { } /** + * Returns the unique source of this resampled image. + */ + private RenderedImage getSource() { + return getSource(0); + } + + /** * Returns the same color model than the source image. * * @return the color model, or {@code null} if unspecified. */ @Override public ColorModel getColorModel() { - return getSource(0).getColorModel(); + return getSource().getColorModel(); + } + + /** + * Gets a property from this image. Current default implementation forwards the following property requests + * to the source image (more properties may be added to this list in future Apache SIS versions): + * + *
+ *
• {@value #SAMPLE_RESOLUTIONS_KEY}
• + *