001 // License: GPL. See LICENSE file for details.
002
003 package org.openstreetmap.josm.gui.layer.geoimage;
004
005 import java.awt.Graphics2D;
006 import java.awt.Image;
007 import java.awt.MediaTracker;
008 import java.awt.Rectangle;
009 import java.awt.Toolkit;
010 import java.awt.image.BufferedImage;
011 import java.util.ArrayList;
012 import java.util.List;
013
014 import org.openstreetmap.josm.Main;
015 import org.openstreetmap.josm.io.CacheFiles;
016
017 public class ThumbsLoader implements Runnable {
018 public static final int maxSize = 120;
019 public static final int minSize = 22;
020 volatile boolean stop = false;
021 List<ImageEntry> data;
022 GeoImageLayer layer;
023 MediaTracker tracker;
024 CacheFiles cache;
025 boolean cacheOff = Main.pref.getBoolean("geoimage.noThumbnailCache", false);
026
027 public ThumbsLoader(GeoImageLayer layer) {
028 this.layer = layer;
029 this.data = new ArrayList<ImageEntry>(layer.data);
030 if (!cacheOff) {
031 cache = new CacheFiles("geoimage-thumbnails", false);
032 cache.setExpire(CacheFiles.EXPIRE_NEVER, false);
033 cache.setMaxSize(120, false);
034 }
035 }
036
037 public void run() {
038 System.err.println("Load Thumbnails");
039 tracker = new MediaTracker(Main.map.mapView);
040 for (int i = 0; i < data.size(); i++) {
041 if (stop) return;
042
043 System.err.print("fetching image "+i);
044
045 data.get(i).thumbnail = loadThumb(data.get(i));
046
047 if (Main.isDisplayingMapView()) {
048 layer.updateOffscreenBuffer = true;
049 Main.map.mapView.repaint();
050 }
051 }
052 layer.updateOffscreenBuffer = true;
053 Main.map.mapView.repaint();
054 (new Thread() { // clean up the garbage - shouldn't hurt
055 @Override
056 public void run() {
057 try {
058 Thread.sleep(200);
059 }
060 catch (InterruptedException ie) {}
061 System.gc();
062 }
063 }).start();
064
065 }
066
067 private BufferedImage loadThumb(ImageEntry entry) {
068 final String cacheIdent = entry.getFile().toString()+":"+maxSize;
069
070 if (!cacheOff) {
071 BufferedImage cached = cache.getImg(cacheIdent);
072 if(cached != null) {
073 System.err.println(" from cache");
074 return cached;
075 }
076 }
077
078 Image img = Toolkit.getDefaultToolkit().createImage(entry.getFile().getPath());
079 tracker.addImage(img, 0);
080 try {
081 tracker.waitForID(0);
082 } catch (InterruptedException e) {
083 System.err.println(" InterruptedException");
084 return null;
085 }
086 if (tracker.isErrorID(1) || img.getWidth(null) <= 0 || img.getHeight(null) <= 0) {
087 System.err.println(" Invalid image");
088 return null;
089 }
090 Rectangle targetSize = ImageDisplay.calculateDrawImageRectangle(
091 new Rectangle(0, 0, img.getWidth(null), img.getHeight(null)),
092 new Rectangle(0, 0, maxSize, maxSize));
093 BufferedImage scaledBI = new BufferedImage(targetSize.width, targetSize.height, BufferedImage.TYPE_INT_RGB);
094 Graphics2D g = scaledBI.createGraphics();
095 while (!g.drawImage(img, 0, 0, targetSize.width, targetSize.height, null))
096 {
097 try {
098 Thread.sleep(10);
099 } catch(InterruptedException ie) {}
100 }
101 g.dispose();
102 tracker.removeImage(img);
103
104 if (scaledBI.getWidth() <= 0 || scaledBI.getHeight() <= 0) {
105 System.err.println(" Invalid image");
106 return null;
107 }
108
109 if (!cacheOff) {
110 cache.saveImg(cacheIdent, scaledBI);
111 }
112
113 System.err.println("");
114 return scaledBI;
115 }
116
117 }