Ignore:
Timestamp:
2009-12-12T15:09:44+01:00 (14 years ago)
Author:
bastiK
Message:

geoimage: improved thumbnails (closes #4101)

File:
1 edited

Legend:

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

    r2606 r2617  
    99import static org.openstreetmap.josm.tools.I18n.trn;
    1010
     11import java.awt.AlphaComposite;
     12import java.awt.Color;
    1113import java.awt.Component;
     14import java.awt.Composite;
     15import java.awt.Dimension;
    1216import java.awt.Graphics2D;
    1317import java.awt.Image;
     
    1923import java.awt.event.MouseEvent;
    2024import java.awt.image.BufferedImage;
     25import java.beans.PropertyChangeListener;
     26import java.beans.PropertyChangeEvent;
    2127import java.io.File;
    2228import java.io.IOException;
     
    5662import com.drew.metadata.exif.GpsDirectory;
    5763
    58 public class GeoImageLayer extends Layer {
     64public class GeoImageLayer extends Layer implements PropertyChangeListener {
    5965
    6066    List<ImageEntry> data;
     
    7177    public long timeoffset = 0;
    7278
    73     boolean loadThumbs;
     79    boolean useThumbs = false;
    7480    ThumbsLoader thumbsloader;
     81    private BufferedImage offscreenBuffer;
     82    boolean updateOffscreenBuffer = true;
    7583
    7684    /*
     
    295303        Collections.sort(data);
    296304        this.data = data;
     305        Main.map.mapView.addPropertyChangeListener(this);
    297306    }
    298307
     
    375384
    376385        setName(l.getName());
    377 
     386    }
     387
     388    private Dimension scaledDimension(Image thumb) {
     389        final double d = Main.map.mapView.getDist100Pixel();
     390        final double size = 40 /*meter*/;     /* size of the photo on the map */
     391        double s = size * 100 /*px*/ / d;
     392
     393        final double sMin = ThumbsLoader.minSize;
     394        final double sMax = ThumbsLoader.maxSize;
     395
     396        if (s < sMin) {
     397            s = sMin;
     398        }
     399        if (s > sMax) {
     400            s = sMax;
     401        }
     402        final double f = s / sMax;  /* scale factor */
     403
     404        if (thumb == null)
     405            return null;
     406
     407        return new Dimension(
     408            (int) Math.round(f * thumb.getWidth(null)),
     409            (int) Math.round(f * thumb.getHeight(null)));
    378410    }
    379411
    380412    @Override
    381413    public void paint(Graphics2D g, MapView mv, Bounds bounds) {
    382 
    383         for (ImageEntry e : data) {
     414        int width = Main.map.mapView.getWidth();
     415        int height = Main.map.mapView.getHeight();
     416        Rectangle clip = g.getClipBounds();
     417        if (useThumbs) {
     418            if (null == offscreenBuffer || offscreenBuffer.getWidth() != width  // reuse the old buffer if possible
     419                    || offscreenBuffer.getHeight() != height) {
     420                offscreenBuffer = new BufferedImage(width, height,
     421                        BufferedImage.TYPE_INT_ARGB);
     422                updateOffscreenBuffer = true;
     423            }
     424
     425            if (updateOffscreenBuffer) {
     426                Graphics2D tempG = offscreenBuffer.createGraphics();
     427                tempG.setColor(new Color(0,0,0,0));
     428                Composite saveComp = tempG.getComposite();
     429                tempG.setComposite(AlphaComposite.Clear);   // remove the old images
     430                tempG.fillRect(0, 0, width, height);
     431                tempG.setComposite(saveComp);
     432
     433                for (ImageEntry e : data) {
     434                    if (e.pos == null)
     435                        continue;
     436                    Point p = mv.getPoint(e.pos);
     437                    if (e.thumbnail != null) {
     438                        Dimension d = scaledDimension(e.thumbnail);
     439                        Rectangle target = new Rectangle(p.x - d.width / 2, p.y - d.height / 2, d.width, d.height);
     440                        if (clip.intersects(target)) {
     441                            tempG.drawImage(e.thumbnail, target.x, target.y, target.width, target.height, null);
     442                        }
     443                    }
     444                    else { // thumbnail not loaded yet
     445                        icon.paintIcon(mv, tempG,
     446                                   p.x - icon.getIconWidth() / 2,
     447                                   p.y - icon.getIconHeight() / 2);
     448                    }
     449                }
     450                updateOffscreenBuffer = false;
     451            }
     452            g.drawImage(offscreenBuffer, 0, 0, null);
     453        }
     454        else {
     455            for (ImageEntry e : data) {
     456                if (e.pos == null)
     457                    continue;
     458                Point p = mv.getPoint(e.pos);
     459                icon.paintIcon(mv, g,
     460                           p.x - icon.getIconWidth() / 2,
     461                           p.y - icon.getIconHeight() / 2);
     462            }
     463        }
     464
     465        if (currentPhoto >= 0 && currentPhoto < data.size()) {
     466            ImageEntry e = data.get(currentPhoto);
     467
    384468            if (e.pos != null) {
    385469                Point p = mv.getPoint(e.pos);
    386                 if (e.thumbnail != null && e.thumbnail.getWidth(null) > 0 && e.thumbnail.getHeight(null) > 0) {
    387                     g.drawImage(e.thumbnail,
    388                                 p.x - e.thumbnail.getWidth(null) / 2,
    389                                 p.y - e.thumbnail.getHeight(null) / 2, null);
    390                 }
    391                 else {
    392                 icon.paintIcon(mv, g,
    393                                p.x - icon.getIconWidth() / 2,
    394                                p.y - icon.getIconHeight() / 2);
    395                 }
    396             }
    397         }
    398 
    399         // Draw the selection on top of the other pictures.
    400         if (currentPhoto >= 0 && currentPhoto < data.size()) {
    401             ImageEntry e = data.get(currentPhoto);
    402 
    403             if (e.pos != null) {
    404                 Point p = mv.getPoint(e.pos);
    405 
    406                 Rectangle r = new Rectangle(p.x - selectedIcon.getIconWidth() / 2,
    407                                             p.y - selectedIcon.getIconHeight() / 2,
    408                                             selectedIcon.getIconWidth(),
    409                                             selectedIcon.getIconHeight());
    410                 selectedIcon.paintIcon(mv, g, r.x, r.y);
     470
     471                if (e.thumbnail != null) {
     472                    Dimension d = scaledDimension(e.thumbnail);
     473                    g.setColor(new Color(128, 0, 0, 122));
     474                    g.fillRect(p.x - d.width / 2, p.y - d.height / 2, d.width, d.height);
     475                } else {
     476                    selectedIcon.paintIcon(mv, g,
     477                                p.x - selectedIcon.getIconWidth() / 2,
     478                                p.y - selectedIcon.getIconHeight() / 2);
     479                }
    411480            }
    412481        }
     
    500569
    501570    public void checkPreviousNextButtons() {
    502         System.err.println("check: " + currentPhoto);
     571//        System.err.println("showing image " + currentPhoto);
    503572        ImageViewerDialog.setNextEnabled(currentPhoto < data.size() - 1);
    504573        ImageViewerDialog.setPreviousEnabled(currentPhoto > 0);
     
    517586            }
    518587        }
     588        updateOffscreenBuffer = true;
    519589        Main.main.map.repaint();
    520590    }
     
    534604
    535605            @Override public void mouseReleased(MouseEvent ev) {
    536 
    537606                if (ev.getButton() != MouseEvent.BUTTON1) {
    538607                    return;
     
    541610                    return;
    542611                }
    543 
    544                 ImageViewerDialog d = ImageViewerDialog.getInstance();
    545612
    546613                for (int i = data.size() - 1; i >= 0; --i) {
     
    549616                        continue;
    550617                    Point p = Main.map.mapView.getPoint(e.pos);
    551                     Rectangle r = new Rectangle(p.x - icon.getIconWidth() / 2,
    552                                                 p.y - icon.getIconHeight() / 2,
    553                                                 icon.getIconWidth(),
    554                                                 icon.getIconHeight());
     618                    Rectangle r;
     619                    if (e.thumbnail != null) {
     620                        Dimension d = scaledDimension(e.thumbnail);
     621                        r = new Rectangle(p.x - d.width / 2, p.y - d.height / 2, d.width, d.height);
     622                    } else {
     623                        r = new Rectangle(p.x - icon.getIconWidth() / 2,
     624                                            p.y - icon.getIconHeight() / 2,
     625                                            icon.getIconWidth(),
     626                                            icon.getIconHeight());
     627                    }
    555628                    if (r.contains(ev.getPoint())) {
    556629                        currentPhoto = i;
     
    560633                    }
    561634                }
    562                 Main.map.mapView.repaint();
    563635            }
    564636        };
     
    577649            public void layerRemoved(Layer oldLayer) {
    578650                if (oldLayer == GeoImageLayer.this) {
     651                    if (thumbsloader != null) {
     652                        thumbsloader.stop = true;
     653                    }
    579654                    Main.map.mapView.removeMouseListener(mouseAdapter);
    580655                    currentPhoto = -1;
     
    585660        });
    586661    }
    587    
    588     @Override
    589     public void destroy() {
    590         if (thumbsloader != null) {
    591             thumbsloader.stop = true;
     662
     663    public void propertyChange(PropertyChangeEvent evt) {
     664        if ("center".equals(evt.getPropertyName()) || "scale".equals(evt.getPropertyName())) {
     665            updateOffscreenBuffer = true;
    592666        }
    593667    }
Note: See TracChangeset for help on using the changeset viewer.