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