Changeset 17983 in josm for trunk/src/org


Ignore:
Timestamp:
2021-07-10T21:39:01+02:00 (3 years ago)
Author:
Don-vip
Message:

fix #21016 - ColorfulFilter not applied to empty tiles (patch by Bjoeni)

Location:
trunk/src/org/openstreetmap/josm/gui/layer
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageDisplay.java

    r17880 r17983  
    3232import org.openstreetmap.josm.gui.layer.imagery.ImageryFilterSettings;
    3333import org.openstreetmap.josm.gui.layer.imagery.ImageryFilterSettings.FilterChangeListener;
     34import org.openstreetmap.josm.gui.util.GuiHelper;
    3435import org.openstreetmap.josm.spi.preferences.Config;
    3536import org.openstreetmap.josm.spi.preferences.PreferenceChangeEvent;
     
    101102    /** Show a background for the error text (may be hard on eyes) */
    102103    private static final BooleanProperty ERROR_MESSAGE_BACKGROUND = new BooleanProperty("geoimage.message.error.background", false);
     104
     105    private updateImageThread updateImageThreadInstance;
     106
     107    private class updateImageThread extends Thread {
     108        private boolean restart;
     109
     110        @Override
     111        public void run() {
     112            updateProcessedImage();
     113            if (restart) {
     114                restart = false;
     115                run();
     116            }
     117        }
     118
     119        public void restart() {
     120            restart = true;
     121            if (!isAlive()) {
     122                restart = false;
     123                updateImageThreadInstance = new updateImageThread();
     124                updateImageThreadInstance.start();
     125            }
     126        }
     127    }
    103128
    104129    @Override
     
    651676    @Override
    652677    public void filterChanged() {
    653         updateProcessedImage();
    654         repaint();
     678        if (updateImageThreadInstance != null) {
     679            updateImageThreadInstance.restart();
     680        } else {
     681            updateImageThreadInstance = new updateImageThread();
     682            updateImageThreadInstance.start();
     683        }
    655684    }
    656685
    657686    private void updateProcessedImage() {
    658687        processedImage = image == null ? null : imageProcessor.process(image);
     688        GuiHelper.runInEDT(() -> repaint());
    659689    }
    660690
  • trunk/src/org/openstreetmap/josm/gui/layer/imagery/ColorfulFilter.java

    r13397 r17983  
    3838    @Override
    3939    public BufferedImage filter(BufferedImage src, BufferedImage dst) {
    40         if (src.getWidth() == 0 || src.getHeight() == 0 || src.getType() == BufferedImage.TYPE_CUSTOM) {
     40        if (src.getWidth() == 0 || src.getHeight() == 0) {
    4141            return src;
    4242        }
    4343
    44         BufferedImage dest = Optional.ofNullable(dst).orElseGet(() -> createCompatibleDestImage(src, null));
    4544        int type = src.getType();
    4645
    47         if (type == BufferedImage.TYPE_BYTE_INDEXED) {
    48             return filterIndexed(src, dest);
    49         }
    50 
    51         DataBuffer srcBuffer = src.getRaster().getDataBuffer();
    52         DataBuffer destBuffer = dest.getRaster().getDataBuffer();
    53         if (!(srcBuffer instanceof DataBufferByte) || !(destBuffer instanceof DataBufferByte)) {
    54             Logging.trace("Cannot apply color filter: Images do not use DataBufferByte.");
    55             return src;
    56         }
    57 
    58         if (type != dest.getType()) {
    59             Logging.trace("Cannot apply color filter: Src / Dest differ in type (" + type + '/' + dest.getType() + ')');
    60             return src;
    61         }
    62         int redOffset;
    63         int greenOffset;
    64         int blueOffset;
    65         int alphaOffset = 0;
    6646        switch (type) {
     47        case BufferedImage.TYPE_BYTE_INDEXED:
    6748        case BufferedImage.TYPE_3BYTE_BGR:
    68             blueOffset = 0;
    69             greenOffset = 1;
    70             redOffset = 2;
    71             break;
    7249        case BufferedImage.TYPE_4BYTE_ABGR:
    7350        case BufferedImage.TYPE_4BYTE_ABGR_PRE:
    74             blueOffset = 1;
    75             greenOffset = 2;
    76             redOffset = 3;
    77             break;
    7851        case BufferedImage.TYPE_INT_ARGB:
    7952        case BufferedImage.TYPE_INT_ARGB_PRE:
    80             redOffset = 0;
    81             greenOffset = 1;
    82             blueOffset = 2;
    83             alphaOffset = 3;
    84             break;
    85         default:
    86             Logging.trace("Cannot apply color filter: Source image is of wrong type (" + type + ").");
    87             return src;
    88         }
    89         doFilter((DataBufferByte) srcBuffer, (DataBufferByte) destBuffer, redOffset, greenOffset, blueOffset,
    90                 alphaOffset, src.getAlphaRaster() != null);
    91         return dest;
     53
     54            BufferedImage dest = Optional.ofNullable(dst).orElseGet(() -> createCompatibleDestImage(src, null));
     55
     56            if (type == BufferedImage.TYPE_BYTE_INDEXED) {
     57                try {
     58                    return filterIndexed(src, dest);
     59                } catch (IllegalArgumentException ex) {
     60                    Logging.warn(ex);
     61                    break;
     62                }
     63            }
     64
     65            DataBuffer srcBuffer = src.getRaster().getDataBuffer();
     66            DataBuffer destBuffer = dest.getRaster().getDataBuffer();
     67            if (!(srcBuffer instanceof DataBufferByte) || !(destBuffer instanceof DataBufferByte)) {
     68                Logging.trace("Images do not use DataBufferByte. Filtering RGB values instead.");
     69                break;
     70            }
     71
     72            if (type != dest.getType()) {
     73                Logging.trace("Src / Dest differ in type (" + type + '/' + dest.getType() + "). Filtering RGB values instead.");
     74                break;
     75            }
     76
     77            int redOffset;
     78            int greenOffset;
     79            int blueOffset;
     80            int alphaOffset = 0;
     81            switch (type) {
     82            case BufferedImage.TYPE_3BYTE_BGR:
     83                blueOffset = 0;
     84                greenOffset = 1;
     85                redOffset = 2;
     86                break;
     87            case BufferedImage.TYPE_4BYTE_ABGR:
     88            case BufferedImage.TYPE_4BYTE_ABGR_PRE:
     89                blueOffset = 1;
     90                greenOffset = 2;
     91                redOffset = 3;
     92                break;
     93            case BufferedImage.TYPE_INT_ARGB:
     94            case BufferedImage.TYPE_INT_ARGB_PRE:
     95                redOffset = 0;
     96                greenOffset = 1;
     97                blueOffset = 2;
     98                alphaOffset = 3;
     99                break;
     100            default:
     101                return doFilterRGB(src);
     102            }
     103
     104            doFilter((DataBufferByte) srcBuffer, (DataBufferByte) destBuffer, redOffset, greenOffset, blueOffset,
     105                    alphaOffset, src.getAlphaRaster() != null);
     106            return dest;
     107        }
     108
     109        return doFilterRGB(src);
    92110    }
    93111
     
    161179    }
    162180
    163     private byte mix(int color, double luminosity) {
     181    private BufferedImage doFilterRGB(BufferedImage src) {
     182        int w = src.getWidth();
     183        int h = src.getHeight();
     184
     185        int[] arr = src.getRGB(0, 0, w, h, null, 0, w);
     186        int argb, a, r, g, b;
     187        double luminosity;
     188
     189        for (int i = 0; i < arr.length; i++) {
     190            argb = arr[i];
     191            a = (argb >> 24) & 0xff;
     192            r = (argb >> 16) & 0xff;
     193            g = (argb >> 8) & 0xff;
     194            b = argb & 0xff;
     195            luminosity = r * LUMINOSITY_RED + g * LUMINOSITY_GREEN + b * LUMINOSITY_BLUE;
     196            r = mixInt(r, luminosity);
     197            g = mixInt(g, luminosity);
     198            b = mixInt(b, luminosity);
     199            argb = a;
     200            argb = (argb << 8) + r;
     201            argb = (argb << 8) + g;
     202            argb = (argb << 8) + b;
     203            arr[i] = argb;
     204        }
     205
     206        BufferedImage dest = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
     207        dest.setRGB(0, 0, w, h, arr, 0, w);
     208        return dest;
     209    }
     210
     211    private int mixInt(int color, double luminosity) {
    164212        int val = (int) (colorfulness * color + (1 - colorfulness) * luminosity);
    165213        if (val < 0) {
    166214            return 0;
    167215        } else if (val > 0xff) {
    168             return (byte) 0xff;
     216            return 0xff;
    169217        } else {
    170             return (byte) val;
    171         }
     218            return val;
     219        }
     220    }
     221
     222    private byte mix(int color, double luminosity) {
     223        return (byte) mixInt(color, luminosity);
    172224    }
    173225
Note: See TracChangeset for help on using the changeset viewer.