Ignore:
Timestamp:
2014-05-15T03:15:28+02:00 (10 years ago)
Author:
Don-vip
Message:

fix #9984 - Add support for WMS tiles defining a transparent color in RGB space (tRNS PNG chunk for example), instead of a proper alpha channel. Surprisingly, Java does not support that out of the box, ImageIO.read always returns opaque images. Allows to switch between this mode and standard mode using WMS layer contextual entry "Use Alpha Channel", for consistency with images defining an alpha channel. Does not impact other images than WMS tiles.

Location:
trunk/src/org/openstreetmap/josm/data/imagery
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/imagery/GeorefImage.java

    r7025 r7132  
    2222import org.openstreetmap.josm.gui.layer.ImageryLayer;
    2323import org.openstreetmap.josm.gui.layer.WMSLayer;
     24import org.openstreetmap.josm.tools.ImageProvider;
    2425
    2526public class GeorefImage implements Serializable {
     
    4647        return layer.getEastNorth(xIndex+1, yIndex+1);
    4748    }
    48 
    4949
    5050    public GeorefImage(WMSLayer layer) {
     
    5757            this.yIndex = yIndex;
    5858            this.image = null;
    59             flushedResizedCachedInstance();
     59            flushResizedCachedInstance();
    6060        }
    6161    }
     
    6565    }
    6666
     67    /**
     68     * Resets this image to initial state and release all resources being used.
     69     * @since 7132
     70     */
     71    public void resetImage() {
     72        if (image != null) {
     73            image.flush();
     74        }
     75        changeImage(null, null);
     76    }
     77
    6778    public void changeImage(State state, BufferedImage image) {
    68         flushedResizedCachedInstance();
     79        flushResizedCachedInstance();
    6980        this.image = image;
    7081        this.state = state;
    71 
     82        if (state == null)
     83            return;
    7284        switch (state) {
    7385        case FAILED:
     
    103115
    104116    public boolean paint(Graphics g, NavigatableComponent nc, int xIndex, int yIndex, int leftEdge, int bottomEdge) {
    105         if (image == null)
     117        if (getImage() == null)
    106118            return false;
    107119
     
    174186
    175187    private void fallbackDraw(Graphics g, Image img, int x, int y, int width, int height, boolean alphaChannel) {
    176         flushedResizedCachedInstance();
     188        flushResizedCachedInstance();
    177189        g.drawImage(
    178190                img, x, y, x + width, y + height,
     
    195207        boolean hasImage = in.readBoolean();
    196208        if (hasImage) {
    197             image = (ImageIO.read(ImageIO.createImageInputStream(in)));
     209            image = ImageProvider.read(ImageIO.createImageInputStream(in), true, WMSLayer.PROP_ALPHA_CHANNEL.get());
    198210        } else {
    199211            in.readObject(); // read null from input stream
     
    213225    }
    214226
    215     public void flushedResizedCachedInstance() {
     227    public void flushResizedCachedInstance() {
    216228        if (reImg != null) {
    217229            BufferedImage img = reImg.get();
     
    223235    }
    224236
    225 
    226237    public BufferedImage getImage() {
    227238        return image;
  • trunk/src/org/openstreetmap/josm/data/imagery/WmsCache.java

    r7033 r7132  
    4242import org.openstreetmap.josm.data.preferences.StringProperty;
    4343import org.openstreetmap.josm.data.projection.Projection;
     44import org.openstreetmap.josm.gui.layer.WMSLayer;
     45import org.openstreetmap.josm.tools.ImageProvider;
    4446import org.openstreetmap.josm.tools.Utils;
    4547
     
    4850    //TODO Property for maximum age of tile, automatically remove old tiles
    4951    //TODO Measure time for partially loading from cache, compare with time to download tile. If slower, disable partial cache
    50     //TODO Do loading from partial cache and downloading at the same time, don't wait for partical cache to load
     52    //TODO Do loading from partial cache and downloading at the same time, don't wait for partial cache to load
    5153
    5254    private static final StringProperty PROP_CACHE_PATH = new StringProperty("imagery.wms-cache.path", "wms");
     
    7072            this.bounds = new ProjectionBounds(east, north, east + tileSize / pixelPerDegree, north + tileSize / pixelPerDegree);
    7173            this.filename = filename;
     74        }
     75
     76        @Override
     77        public String toString() {
     78            return "CacheEntry [pixelPerDegree=" + pixelPerDegree + ", east=" + east + ", north=" + north + ", bounds="
     79                    + bounds + ", filename=" + filename + ", lastUsed=" + lastUsed + ", lastModified=" + lastModified
     80                    + "]";
    7281        }
    7382    }
     
    299308    }
    300309
    301     private BufferedImage loadImage(ProjectionEntries projectionEntries, CacheEntry entry) throws IOException {
    302 
     310    private BufferedImage loadImage(ProjectionEntries projectionEntries, CacheEntry entry, boolean enforceTransparency) throws IOException {
    303311        synchronized (this) {
    304312            entry.lastUsed = System.currentTimeMillis();
     
    307315            if (memCache != null) {
    308316                BufferedImage result = memCache.get();
    309                 if (result != null)
    310                     return result;
     317                if (result != null) {
     318                    if (enforceTransparency == ImageProvider.isTransparencyForced(result)) {
     319                        return result;
     320                    } else if (Main.isDebugEnabled()) {
     321                        Main.debug("Skipping "+entry+" from memory cache (transparency enforcement)");
     322                    }
     323                }
    311324            }
    312325        }
     
    314327        try {
    315328            // Reading can't be in synchronized section, it's too slow
    316             BufferedImage result = ImageIO.read(getImageFile(projectionEntries, entry));
     329            BufferedImage result = ImageProvider.read(getImageFile(projectionEntries, entry), true, enforceTransparency);
    317330            synchronized (this) {
    318331                if (result == null) {
     
    354367        if (entry != null) {
    355368            try {
    356                 return loadImage(projectionEntries, entry);
     369                return loadImage(projectionEntries, entry, WMSLayer.PROP_ALPHA_CHANNEL.get());
    357370            } catch (IOException e) {
    358371                Main.error("Unable to load file from wms cache");
     
    364377    }
    365378
    366     public  BufferedImage getPartialMatch(Projection projection, double pixelPerDegree, double east, double north) {
     379    public BufferedImage getPartialMatch(Projection projection, double pixelPerDegree, double east, double north) {
    367380        ProjectionEntries projectionEntries;
    368381        List<CacheEntry> matches;
     
    390403                return null;
    391404
    392 
    393405            Collections.sort(matches, new Comparator<CacheEntry>() {
    394406                @Override
     
    399411        }
    400412
    401         //TODO Use alpha layer only when enabled on wms layer
    402         BufferedImage result = new BufferedImage(tileSize, tileSize, BufferedImage.TYPE_4BYTE_ABGR);
     413        // Use alpha layer only when enabled on wms layer
     414        boolean alpha = WMSLayer.PROP_ALPHA_CHANNEL.get();
     415        BufferedImage result = new BufferedImage(tileSize, tileSize,
     416                alpha ? BufferedImage.TYPE_4BYTE_ABGR : BufferedImage.TYPE_3BYTE_BGR);
    403417        Graphics2D g = result.createGraphics();
    404 
    405418
    406419        boolean drawAtLeastOnce = false;
     
    409422            BufferedImage img;
    410423            try {
    411                 img = loadImage(projectionEntries, ce);
     424                // Enforce transparency only when alpha enabled on wms layer too
     425                img = loadImage(projectionEntries, ce, alpha);
    412426                localCache.put(ce, new SoftReference<>(img));
    413427            } catch (IOException e) {
Note: See TracChangeset for help on using the changeset viewer.