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 }