source: josm/trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ThumbsLoader.java@ 8041

Last change on this file since 8041 was 7956, checked in by bastiK, 9 years ago

fixed #10962 - Photo orientation should not be ignored for thumbnails

  • Property svn:eol-style set to native
File size: 4.1 KB
Line 
1// License: GPL. See LICENSE file for details.
2package org.openstreetmap.josm.gui.layer.geoimage;
3
4import java.awt.Graphics2D;
5import java.awt.Image;
6import java.awt.MediaTracker;
7import java.awt.Rectangle;
8import java.awt.Toolkit;
9import java.awt.geom.AffineTransform;
10import java.awt.image.BufferedImage;
11import java.util.ArrayList;
12import java.util.List;
13
14import org.openstreetmap.josm.Main;
15import org.openstreetmap.josm.io.CacheFiles;
16import org.openstreetmap.josm.tools.ExifReader;
17
18public class ThumbsLoader implements Runnable {
19 public static final int maxSize = 120;
20 public static final int minSize = 22;
21 public volatile boolean stop = false;
22 List<ImageEntry> data;
23 GeoImageLayer layer;
24 MediaTracker tracker;
25 CacheFiles cache;
26 boolean cacheOff = Main.pref.getBoolean("geoimage.noThumbnailCache", false);
27
28 public ThumbsLoader(GeoImageLayer layer) {
29 this.layer = layer;
30 this.data = new ArrayList<>(layer.data);
31 if (!cacheOff) {
32 cache = new CacheFiles("geoimage-thumbnails", false);
33 cache.setExpire(CacheFiles.EXPIRE_NEVER, false);
34 cache.setMaxSize(120, false);
35 }
36 }
37
38 @Override
39 public void run() {
40 Main.debug("Load Thumbnails");
41 tracker = new MediaTracker(Main.map.mapView);
42 for (int i = 0; i < data.size(); i++) {
43 if (stop) return;
44
45 // Do not load thumbnails that were loaded before.
46 if (data.get(i).thumbnail == null) {
47 data.get(i).thumbnail = loadThumb(data.get(i));
48
49 if (Main.isDisplayingMapView()) {
50 layer.updateOffscreenBuffer = true;
51 Main.map.mapView.repaint();
52 }
53 }
54 }
55 layer.thumbsLoaded();
56 layer.updateOffscreenBuffer = true;
57 Main.map.mapView.repaint();
58 }
59
60 private BufferedImage loadThumb(ImageEntry entry) {
61 final String cacheIdent = entry.getFile().toString()+":"+maxSize;
62
63 if (!cacheOff) {
64 BufferedImage cached = cache.getImg(cacheIdent);
65 if (cached != null) {
66 Main.debug(" from cache");
67 return cached;
68 }
69 }
70
71 Image img = Toolkit.getDefaultToolkit().createImage(entry.getFile().getPath());
72 tracker.addImage(img, 0);
73 try {
74 tracker.waitForID(0);
75 } catch (InterruptedException e) {
76 Main.error(" InterruptedException while loading thumb");
77 return null;
78 }
79 if (tracker.isErrorID(1) || img.getWidth(null) <= 0 || img.getHeight(null) <= 0) {
80 Main.error(" Invalid image");
81 return null;
82 }
83
84 final int w = img.getWidth(null);
85 final int h = img.getHeight(null);
86 final int hh, ww;
87 if (ExifReader.orientationSwitchesDimensions(entry.getExifOrientation())) {
88 ww = h;
89 hh = w;
90 } else {
91 ww = w;
92 hh = h;
93 }
94
95 Rectangle targetSize = ImageDisplay.calculateDrawImageRectangle(
96 new Rectangle(0, 0, ww, hh),
97 new Rectangle(0, 0, maxSize, maxSize));
98 BufferedImage scaledBI = new BufferedImage(targetSize.width, targetSize.height, BufferedImage.TYPE_INT_RGB);
99 Graphics2D g = scaledBI.createGraphics();
100
101 final AffineTransform restoreOrientation = ExifReader.getRestoreOrientationTransform(entry.getExifOrientation(), w, h);
102 final AffineTransform scale = AffineTransform.getScaleInstance((double) targetSize.width / ww, (double) targetSize.height / hh);
103 scale.concatenate(restoreOrientation);
104
105 while (!g.drawImage(img, scale, null)) {
106 try {
107 Thread.sleep(10);
108 } catch(InterruptedException ie) {
109 Main.warn("InterruptedException while drawing thumb");
110 }
111 }
112 g.dispose();
113 tracker.removeImage(img);
114
115 if (scaledBI.getWidth() <= 0 || scaledBI.getHeight() <= 0) {
116 Main.error(" Invalid image");
117 return null;
118 }
119
120 if (!cacheOff) {
121 cache.saveImg(cacheIdent, scaledBI);
122 }
123
124 return scaledBI;
125 }
126
127}
Note: See TracBrowser for help on using the repository browser.