sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] 02/06: Apply mask on the image of positional errors.
Date Mon, 29 Jun 2020 17:31:18 GMT
This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit 5fdfd59d565cbf7db8ad6c0d8efa6b0778b09792
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Mon Jun 29 11:07:15 2020 +0200

    Apply mask on the image of positional errors.
---
 .../apache/sis/internal/gui/ImageConverter.java    | 23 +++++++++++++++-
 .../java/org/apache/sis/image/ImageProcessor.java  | 17 +++++++++++-
 .../java/org/apache/sis/image/RecoloredImage.java  | 31 ++++++++++++++++++++++
 .../org/apache/sis/internal/feature/Resources.java |  5 ++++
 .../sis/internal/feature/Resources.properties      |  1 +
 .../sis/internal/feature/Resources_fr.properties   |  1 +
 6 files changed, 76 insertions(+), 2 deletions(-)

diff --git a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/ImageConverter.java
b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/ImageConverter.java
index 091910e..e9efc48 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/ImageConverter.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/ImageConverter.java
@@ -28,8 +28,11 @@ import javafx.scene.image.PixelFormat;
 import javafx.scene.image.PixelWriter;
 import javafx.scene.image.WritableImage;
 import org.apache.sis.image.ImageProcessor;
+import org.apache.sis.image.PlanarImage;
 import org.apache.sis.internal.coverage.j2d.ImageUtilities;
+import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.jdk9.JDK9;
+import org.apache.sis.util.logging.Logging;
 import org.apache.sis.math.Statistics;
 
 
@@ -102,7 +105,6 @@ final class ImageConverter extends Task<Statistics[]> {
                                       height / (double) bounds.height);
         /*
          * Use a uniform scale. At least one of `width` or `height` will be unchanged.
-         * The image will be shown fully, at the cost of some space being unused.
          */
         width  = (int) Math.round(scale * bounds.width);
         height = (int) Math.round(scale * bounds.height);
@@ -112,10 +114,14 @@ final class ImageConverter extends Task<Statistics[]> {
         final ImageProcessor processor  = new ImageProcessor();
         final Statistics[]   statistics = processor.getStatistics(source, bounds);
         final RenderedImage  image      = processor.stretchColorRamp(source, JDK9.mapOf("multStdDev",
3, "statistics", statistics));
+        final RenderedImage  mask       = getMask(processor);
         final BufferedImage  buffer     = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB_PRE);
         final Graphics2D     graphics   = buffer.createGraphics();
         try {
             graphics.drawRenderedImage(image, toCanvas);
+            if (mask != null) {
+                graphics.drawRenderedImage(mask, toCanvas);
+            }
         } finally {
             graphics.dispose();
         }
@@ -124,6 +130,21 @@ final class ImageConverter extends Task<Statistics[]> {
     }
 
     /**
+     * If there is a mask that we can apply on the image, returns that mask. Otherwise returns
0.
+     * Current implementation returns the mask as a transparent yellow image.
+     */
+    private RenderedImage getMask(final ImageProcessor processor) {
+        final Object mask = source.getProperty(PlanarImage.MASK_KEY);
+        if (mask instanceof RenderedImage) try {
+            return processor.recolor((RenderedImage) mask, new int[] {0, 0x20FFFF00});
+        } catch (IllegalArgumentException e) {
+            // Ignore, we will not apply any mask. Declare PropertyView.setImage(…) as
the public method.
+            Logging.recoverableException(Logging.getLogger(Loggers.APPLICATION), PropertyView.class,
"setImage", e);
+        }
+        return null;
+    }
+
+    /**
      * Sets the JavaFX image to the ARGB values computed in background thread.
      */
     @Override
diff --git a/core/sis-feature/src/main/java/org/apache/sis/image/ImageProcessor.java b/core/sis-feature/src/main/java/org/apache/sis/image/ImageProcessor.java
index 913cd15..a8da696 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/image/ImageProcessor.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/image/ImageProcessor.java
@@ -29,6 +29,7 @@ import java.awt.image.SampleModel;
 import java.awt.image.BufferedImage;
 import java.awt.image.RenderedImage;
 import java.awt.image.ImagingOpException;
+import java.awt.image.IndexColorModel;
 import javax.measure.Quantity;
 import org.opengis.referencing.operation.MathTransform;
 import org.apache.sis.math.Statistics;
@@ -578,6 +579,20 @@ public class ImageProcessor implements Cloneable {
     }
 
     /**
+     * Changes the color ramp of the given image. The given image must use an {@link IndexColorModel}
+     * with the same number of colors than the given {@code ARGB} length.
+     *
+     * @param  source  the image for which to replace the color model.
+     * @param  ARGB    Alpha=Red=Green=Blue codes of new color map.
+     * @return image using the given color map.
+     */
+    public RenderedImage recolor(final RenderedImage source, final int[] ARGB) {
+        ArgumentChecks.ensureNonNull("source", source);
+        ArgumentChecks.ensureNonNull("ARGB", ARGB);
+        return RecoloredImage.recolor(source, ARGB);
+    }
+
+    /**
      * Creates a new image which will resample the given image. The resampling operation
is defined
      * by a non-linear transform from the <em>new</em> image to the specified
<em>source</em> image.
      * That transform should map {@linkplain org.opengis.referencing.datum.PixelInCell#CELL_CENTER
pixel centers}.
@@ -595,9 +610,9 @@ public class ImageProcessor implements Cloneable {
      * @return resampled image (may be {@code source}).
      */
     public RenderedImage resample(RenderedImage source, final Rectangle bounds, MathTransform
toSource) {
+        ArgumentChecks.ensureNonNull("source",   source);
         ArgumentChecks.ensureNonNull("bounds",   bounds);
         ArgumentChecks.ensureNonNull("toSource", toSource);
-        ArgumentChecks.ensureNonNull("source",   source);
         final ColorModel  cm = source.getColorModel();
         final SampleModel sm = source.getSampleModel();
         boolean isIdentity = toSource.isIdentity();
diff --git a/core/sis-feature/src/main/java/org/apache/sis/image/RecoloredImage.java b/core/sis-feature/src/main/java/org/apache/sis/image/RecoloredImage.java
index 28a8205..e305976 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/image/RecoloredImage.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/image/RecoloredImage.java
@@ -19,13 +19,17 @@ package org.apache.sis.image;
 import java.util.Map;
 import java.awt.Shape;
 import java.awt.image.ColorModel;
+import java.awt.image.IndexColorModel;
 import java.awt.image.SampleModel;
 import java.awt.image.RenderedImage;
 import org.apache.sis.internal.coverage.j2d.ColorModelFactory;
 import org.apache.sis.internal.coverage.j2d.ImageUtilities;
+import org.apache.sis.internal.feature.Resources;
+import org.apache.sis.internal.util.Strings;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.math.Statistics;
+import org.apache.sis.util.Classes;
 
 
 /**
@@ -157,6 +161,33 @@ final class RecoloredImage extends ImageAdapter {
     }
 
     /**
+     * Implementation of {@link ImageProcessor#recolor(RenderedImage, int[])}.
+     */
+    static RenderedImage recolor(final RenderedImage source, final int[] ARGB) {
+        String expected, actual;                                // To be used in case of
error.
+        final ColorModel cm = source.getColorModel();
+        if (cm instanceof IndexColorModel) {
+            final IndexColorModel icm = (IndexColorModel) cm;
+            if (icm.getMapSize() == ARGB.length) {
+                final IndexColorModel newColors = ColorModelFactory.createIndexColorModel(ARGB,
+                                                    ImageUtilities.getNumBands(source),
+                                                    ImageUtilities.getVisibleBand(source),
-1);
+                if (cm.equals(newColors)) {
+                    return source;
+                }
+                return ImageProcessor.unique(new RecoloredImage(source, newColors));
+            } else {
+                expected = Strings.toIndexed("IndexColorModel", icm.getMapSize());
+                actual   = Strings.toIndexed("IndexColorModel", ARGB.length);
+            }
+        } else {
+            expected = "IndexColorModel";
+            actual   = Classes.getShortClassName(cm.getClass());
+        }
+        throw new IllegalArgumentException(Resources.format(Resources.Keys.UnsupportedColorModel_2,
expected, actual));
+    }
+
+    /**
      * Returns the color model of this image.
      */
     @Override
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Resources.java
b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Resources.java
index f4822a7..cd23c52 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Resources.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Resources.java
@@ -438,6 +438,11 @@ public final class Resources extends IndexedResourceBundle {
         public static final short UnspecifiedTransform = 54;
 
         /**
+         * Unsupported color model. Expected ‘{0}’ but got ‘{1}’.
+         */
+        public static final short UnsupportedColorModel_2 = 76;
+
+        /**
          * Unsupported geometry {0}D object.
          */
         public static final short UnsupportedGeometryObject_1 = 20;
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Resources.properties
b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Resources.properties
index 27de5d3..2455f2f 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Resources.properties
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Resources.properties
@@ -92,4 +92,5 @@ UnspecifiedCRS                    = Coordinate reference system is unspecified.
 UnspecifiedGridExtent             = Grid extent is unspecified.
 UnspecifiedRasterData             = Raster data are unspecified.
 UnspecifiedTransform              = Coordinates transform is unspecified.
+UnsupportedColorModel_2           = Unsupported color model. Expected \u2018{0}\u2019 but
got \u2018{1}\u2019.
 UnsupportedGeometryObject_1       = Unsupported geometry {0}D object.
diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Resources_fr.properties
b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Resources_fr.properties
index 0d0972e..41bcf6d 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Resources_fr.properties
+++ b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/Resources_fr.properties
@@ -98,4 +98,5 @@ UnspecifiedCRS                    = Le syst\u00e8me de r\u00e9f\u00e9rence
des c
 UnspecifiedGridExtent             = L\u2019\u00e9tendue de la grille n\u2019a pas \u00e9t\u00e9
sp\u00e9cifi\u00e9e.
 UnspecifiedRasterData             = Les donn\u00e9es du raster n\u2019ont pas \u00e9t\u00e9
sp\u00e9cifi\u00e9es.
 UnspecifiedTransform              = La transformation de coordonn\u00e9es n\u2019a pas \u00e9t\u00e9
sp\u00e9cifi\u00e9e.
+UnsupportedColorModel_2           = Mod\u00e8le de couleurs non-support\u00e9. On attendait
\u2018{0}\u2019 alors que \u2018{1}\u2019 a \u00e9t\u00e9 trouv\u00e9.
 UnsupportedGeometryObject_1       = Object g\u00e9om\u00e9trique {0}D non-support\u00e9.


Mime
View raw message