001// License: GPL. See LICENSE file for details. 002package org.openstreetmap.josm.gui.layer.geoimage; 003 004import java.awt.Graphics2D; 005import java.awt.Image; 006import java.awt.MediaTracker; 007import java.awt.Rectangle; 008import java.awt.Toolkit; 009import java.awt.image.BufferedImage; 010import java.util.ArrayList; 011import java.util.List; 012 013import org.openstreetmap.josm.Main; 014import org.openstreetmap.josm.io.CacheFiles; 015 016public class ThumbsLoader implements Runnable { 017 public static final int maxSize = 120; 018 public static final int minSize = 22; 019 volatile boolean stop = false; 020 List<ImageEntry> data; 021 GeoImageLayer layer; 022 MediaTracker tracker; 023 CacheFiles cache; 024 boolean cacheOff = Main.pref.getBoolean("geoimage.noThumbnailCache", false); 025 026 public ThumbsLoader(GeoImageLayer layer) { 027 this.layer = layer; 028 this.data = new ArrayList<ImageEntry>(layer.data); 029 if (!cacheOff) { 030 cache = new CacheFiles("geoimage-thumbnails", false); 031 cache.setExpire(CacheFiles.EXPIRE_NEVER, false); 032 cache.setMaxSize(120, false); 033 } 034 } 035 036 @Override 037 public void run() { 038 Main.debug("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 } 055 056 private BufferedImage loadThumb(ImageEntry entry) { 057 final String cacheIdent = entry.getFile().toString()+":"+maxSize; 058 059 if (!cacheOff) { 060 BufferedImage cached = cache.getImg(cacheIdent); 061 if (cached != null) { 062 Main.debug(" from cache"); 063 return cached; 064 } 065 } 066 067 Image img = Toolkit.getDefaultToolkit().createImage(entry.getFile().getPath()); 068 tracker.addImage(img, 0); 069 try { 070 tracker.waitForID(0); 071 } catch (InterruptedException e) { 072 Main.error(" InterruptedException while loading thumb"); 073 return null; 074 } 075 if (tracker.isErrorID(1) || img.getWidth(null) <= 0 || img.getHeight(null) <= 0) { 076 Main.error(" Invalid image"); 077 return null; 078 } 079 Rectangle targetSize = ImageDisplay.calculateDrawImageRectangle( 080 new Rectangle(0, 0, img.getWidth(null), img.getHeight(null)), 081 new Rectangle(0, 0, maxSize, maxSize)); 082 BufferedImage scaledBI = new BufferedImage(targetSize.width, targetSize.height, BufferedImage.TYPE_INT_RGB); 083 Graphics2D g = scaledBI.createGraphics(); 084 while (!g.drawImage(img, 0, 0, targetSize.width, targetSize.height, null)) { 085 try { 086 Thread.sleep(10); 087 } catch(InterruptedException ie) { 088 Main.warn("InterruptedException while drawing thumb"); 089 } 090 } 091 g.dispose(); 092 tracker.removeImage(img); 093 094 if (scaledBI.getWidth() <= 0 || scaledBI.getHeight() <= 0) { 095 Main.error(" Invalid image"); 096 return null; 097 } 098 099 if (!cacheOff) { 100 cache.saveImg(cacheIdent, scaledBI); 101 } 102 103 return scaledBI; 104 } 105 106}