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<>(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 // Do not load thumbnails that were loaded before. 044 if (data.get(i).thumbnail == null) { 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 } 053 layer.updateOffscreenBuffer = true; 054 Main.map.mapView.repaint(); 055 } 056 057 private BufferedImage loadThumb(ImageEntry entry) { 058 final String cacheIdent = entry.getFile().toString()+":"+maxSize; 059 060 if (!cacheOff) { 061 BufferedImage cached = cache.getImg(cacheIdent); 062 if (cached != null) { 063 Main.debug(" from cache"); 064 return cached; 065 } 066 } 067 068 Image img = Toolkit.getDefaultToolkit().createImage(entry.getFile().getPath()); 069 tracker.addImage(img, 0); 070 try { 071 tracker.waitForID(0); 072 } catch (InterruptedException e) { 073 Main.error(" InterruptedException while loading thumb"); 074 return null; 075 } 076 if (tracker.isErrorID(1) || img.getWidth(null) <= 0 || img.getHeight(null) <= 0) { 077 Main.error(" Invalid image"); 078 return null; 079 } 080 Rectangle targetSize = ImageDisplay.calculateDrawImageRectangle( 081 new Rectangle(0, 0, img.getWidth(null), img.getHeight(null)), 082 new Rectangle(0, 0, maxSize, maxSize)); 083 BufferedImage scaledBI = new BufferedImage(targetSize.width, targetSize.height, BufferedImage.TYPE_INT_RGB); 084 Graphics2D g = scaledBI.createGraphics(); 085 while (!g.drawImage(img, 0, 0, targetSize.width, targetSize.height, null)) { 086 try { 087 Thread.sleep(10); 088 } catch(InterruptedException ie) { 089 Main.warn("InterruptedException while drawing thumb"); 090 } 091 } 092 g.dispose(); 093 tracker.removeImage(img); 094 095 if (scaledBI.getWidth() <= 0 || scaledBI.getHeight() <= 0) { 096 Main.error(" Invalid image"); 097 return null; 098 } 099 100 if (!cacheOff) { 101 cache.saveImg(cacheIdent, scaledBI); 102 } 103 104 return scaledBI; 105 } 106 107}