Changeset 4241 in josm for trunk


Ignore:
Timestamp:
2011-07-14T17:00:22+02:00 (13 years ago)
Author:
bastiK
Message:

applied #5605 - Geotagged image viewer should rotate images according to EXIF orientation tag (patch by m.zdila, some modifications)

Location:
trunk/src/org/openstreetmap/josm
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java

    r3408 r4241  
    3333import java.util.Comparator;
    3434import java.util.Date;
    35 import java.util.Hashtable;
    3635import java.util.Iterator;
    3736import java.util.List;
    3837import java.util.TimeZone;
    39 import java.util.Vector;
    4038import java.util.zip.GZIPInputStream;
    4139
     
    348346                public void valueChanged(ListSelectionEvent arg0) {
    349347                    int index = imgList.getSelectedIndex();
    350                     imgDisp.setImage(yLayer.data.get(index).getFile());
     348                    Integer orientation = null;
     349                    try {
     350                        orientation = ExifReader.readOrientation(yLayer.data.get(index).getFile());
     351                    } catch (Exception e) {
     352                    }
     353                    imgDisp.setImage(yLayer.data.get(index).getFile(), orientation);
    351354                    Date date = yLayer.data.get(index).getExifTime();
    352355                    if (date != null) {
     
    380383                        return;
    381384
    382                     imgDisp.setImage(sel);
     385                    Integer orientation = null;
     386                    try {
     387                        orientation = ExifReader.readOrientation(sel);
     388                    } catch (Exception e) {
     389                    }
     390                    imgDisp.setImage(sel, orientation);
    383391
    384392                    Date date = null;
  • trunk/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java

    r4010 r4241  
    6363import com.drew.metadata.Directory;
    6464import com.drew.metadata.Metadata;
     65import com.drew.metadata.MetadataException;
     66import com.drew.metadata.exif.ExifDirectory;
    6567import com.drew.metadata.exif.GpsDirectory;
    6668
     
    509511        double lon, lat;
    510512        Metadata metadata = null;
    511         Directory dir = null;
     513        Directory dirExif = null, dirGps = null;
    512514
    513515        try {
    514516            metadata = JpegMetadataReader.readMetadata(e.getFile());
    515             dir = metadata.getDirectory(GpsDirectory.class);
     517            dirExif = metadata.getDirectory(ExifDirectory.class);
     518            dirGps = metadata.getDirectory(GpsDirectory.class);
    516519        } catch (CompoundException p) {
    517520            e.setExifCoor(null);
     
    521524
    522525        try {
     526            int orientation = dirExif.getInt(ExifDirectory.TAG_ORIENTATION);
     527            e.setExifOrientation(orientation);
     528        } catch (MetadataException ex) {
     529        }
     530       
     531        try {
    523532            // longitude
    524533
    525             Rational[] components = dir.getRationalArray(GpsDirectory.TAG_GPS_LONGITUDE);
     534            Rational[] components = dirGps.getRationalArray(GpsDirectory.TAG_GPS_LONGITUDE);
    526535
    527536            deg = components[0].doubleValue();
     
    534543            lon = (Double.isNaN(deg) ? 0 : deg + (Double.isNaN(min) ? 0 : (min / 60)) + (Double.isNaN(sec) ? 0 : (sec / 3600)));
    535544
    536             if (dir.getString(GpsDirectory.TAG_GPS_LONGITUDE_REF).charAt(0) == 'W') {
     545            if (dirGps.getString(GpsDirectory.TAG_GPS_LONGITUDE_REF).charAt(0) == 'W') {
    537546                lon = -lon;
    538547            }
     
    540549            // latitude
    541550
    542             components = dir.getRationalArray(GpsDirectory.TAG_GPS_LATITUDE);
     551            components = dirGps.getRationalArray(GpsDirectory.TAG_GPS_LATITUDE);
    543552
    544553            deg = components[0].doubleValue();
     
    554563                throw new IllegalArgumentException();
    555564
    556             if (dir.getString(GpsDirectory.TAG_GPS_LATITUDE_REF).charAt(0) == 'S') {
     565            if (dirGps.getString(GpsDirectory.TAG_GPS_LATITUDE_REF).charAt(0) == 'S') {
    557566                lat = -lat;
    558567            }
     
    566575            // Try to read lon/lat as double value (Nonstandard, created by some cameras -> #5220)
    567576            try {
    568                 Double longitude = dir.getDouble(GpsDirectory.TAG_GPS_LONGITUDE);
    569                 Double latitude = dir.getDouble(GpsDirectory.TAG_GPS_LATITUDE);
     577                Double longitude = dirGps.getDouble(GpsDirectory.TAG_GPS_LONGITUDE);
     578                Double latitude = dirGps.getDouble(GpsDirectory.TAG_GPS_LATITUDE);
    570579                if (longitude == null || latitude == null)
    571580                    throw new CompoundException("");
     
    590599
    591600        try {
    592             direction = dir.getRational(GpsDirectory.TAG_GPS_IMG_DIRECTION);
     601            direction = dirGps.getRational(GpsDirectory.TAG_GPS_IMG_DIRECTION);
    593602            if (direction != null) {
    594603                e.setExifImgDir(direction.doubleValue());
  • trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageDisplay.java

    r3479 r4241  
    1010import java.awt.FontMetrics;
    1111import java.awt.Graphics;
     12import java.awt.Graphics2D;
    1213import java.awt.Image;
    1314import java.awt.MediaTracker;
     
    2021import java.awt.event.MouseWheelEvent;
    2122import java.awt.event.MouseWheelListener;
     23import java.awt.geom.AffineTransform;
    2224import java.awt.geom.Rectangle2D;
     25import java.awt.image.BufferedImage;
    2326import java.io.File;
    2427
     
    3437    /** The image currently displayed */
    3538    private Image image = null;
    36 
     39   
    3740    /** The image currently displayed */
    3841    private boolean errorLoading = false;
     
    5659    private class LoadImageRunnable implements Runnable {
    5760
    58         File file = null;
    59 
    60         public LoadImageRunnable(File file) {
     61        private File file;
     62        private int orientation;
     63
     64        public LoadImageRunnable(File file, Integer orientation) {
    6165            this.file = file;
     66            this.orientation = orientation == null ? -1 : orientation;
    6267        }
    6368
     
    9095                    return;
    9196                }
     97
    9298                ImageDisplay.this.image = img;
    9399                visibleRect = new Rectangle(0, 0, img.getWidth(null), img.getHeight(null));
     100
     101                final int w = (int) visibleRect.getWidth();
     102                final int h = (int) visibleRect.getHeight();
     103
     104                outer: {
     105                    final int hh, ww, q;
     106                    final double ax, ay;
     107                    switch (orientation) {
     108                    case 8:
     109                        q = -1;
     110                        ax = w / 2;
     111                        ay = w / 2;
     112                        ww = h;
     113                        hh = w;
     114                        break;
     115                    case 3:
     116                        q = 2;
     117                        ax = w / 2;
     118                        ay = h / 2;
     119                        ww = w;
     120                        hh = h;
     121                        break;
     122                    case 6:
     123                        q = 1;
     124                        ax = h / 2;
     125                        ay = h / 2;
     126                        ww = h;
     127                        hh = w;
     128                        break;
     129                    default:
     130                        break outer;
     131                    }
     132
     133                    final BufferedImage rot = new BufferedImage(ww, hh, BufferedImage.TYPE_INT_RGB);
     134                    final AffineTransform xform = AffineTransform.getQuadrantRotateInstance(q, ax, ay);
     135                    final Graphics2D g = rot.createGraphics();
     136                    g.drawImage(image, xform, null);
     137                    g.dispose();
     138
     139                    visibleRect.setSize(ww, hh);
     140                    image.flush();
     141                    ImageDisplay.this.image = rot;
     142                }
     143
    94144                selectedRect = null;
    95145                errorLoading = error;
     
    394444    }
    395445
    396     public void setImage(File file) {
     446    public void setImage(File file, Integer orientation) {
    397447        synchronized(this) {
    398448            this.file = file;
     
    403453        repaint();
    404454        if (file != null) {
    405             new Thread(new LoadImageRunnable(file)).start();
     455            new Thread(new LoadImageRunnable(file, orientation)).start();
    406456        }
    407457    }
  • trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageEntry.java

    r3530 r4241  
    1919final public class ImageEntry implements Comparable<ImageEntry>, Cloneable {
    2020    private File file;
     21    private Integer exifOrientation;
    2122    private LatLon exifCoor;
    2223    private Double exifImgDir;
     
    7374        return file;
    7475    }
     76    public Integer getExifOrientation() {
     77        return exifOrientation;
     78    }
    7579    public Date getExifTime() {
    7680        return exifTime;
     
    100104    void setFile(File file) {
    101105        this.file = file;
     106    }
     107    void setExifOrientation(Integer exifOrientation) {
     108        this.exifOrientation = exifOrientation;
    102109    }
    103110    void setExifTime(Date exifTime) {
  • trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageViewerDialog.java

    r3263 r4241  
    230230
    231231        if (entry != null) {
    232             imgDisplay.setImage(entry.getFile());
     232            imgDisplay.setImage(entry.getFile(), entry.getExifOrientation());
    233233            setTitle("Geotagged Images" + (entry.getFile() != null ? " - " + entry.getFile().getName() : ""));
    234234            StringBuffer osd = new StringBuffer(entry.getFile() != null ? entry.getFile().getName() : "");
     
    253253            imgDisplay.setOsdText(osd.toString());
    254254        } else {
    255             imgDisplay.setImage(null);
     255            imgDisplay.setImage(null, null);
    256256            imgDisplay.setOsdText("");
    257257        }
  • trunk/src/org/openstreetmap/josm/tools/ExifReader.java

    r1169 r4241  
    88
    99import com.drew.imaging.jpeg.JpegMetadataReader;
     10import com.drew.imaging.jpeg.JpegProcessingException;
    1011import com.drew.metadata.Directory;
    1112import com.drew.metadata.Metadata;
     13import com.drew.metadata.MetadataException;
    1214import com.drew.metadata.Tag;
     15import com.drew.metadata.exif.ExifDirectory;
    1316
    1417/**
     
    3841        return date;
    3942    }
     43
     44    @SuppressWarnings("unchecked") public static Integer readOrientation(File filename) throws ParseException {
     45        Integer orientation = null;
     46        try {
     47            final Metadata metadata = JpegMetadataReader.readMetadata(filename);
     48            final Directory dir = metadata.getDirectory(ExifDirectory.class);
     49            orientation = dir.getInt(ExifDirectory.TAG_ORIENTATION);
     50        } catch (JpegProcessingException e) {
     51            e.printStackTrace();
     52        } catch (MetadataException e) {
     53            e.printStackTrace();
     54        }
     55        return orientation;
     56    }
     57
    4058}
Note: See TracChangeset for help on using the changeset viewer.