Ignore:
Timestamp:
2016-01-31T11:38:09+01:00 (9 years ago)
Author:
nokutu
Message:

Replace the image reading methods in MapillaryUtils by the new ImageUtil class

Changes to the previous behaviour:

  • directories are now recursively traversed instead of reading only the top level
  • JPG- and PNG-files are now recognized by their magic bytes instead of the file extension
  • the number of publicly visible methods for image reading has been reduced to one, which can process both files and directories as well as JPGs and PNGs
Location:
applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/actions/MapillaryImportAction.java

    r31918 r32034  
    1212
    1313import javax.swing.JFileChooser;
    14 import javax.swing.filechooser.FileNameExtensionFilter;
    1514
    16 import org.apache.commons.imaging.ImageReadException;
    1715import org.openstreetmap.josm.Main;
    1816import org.openstreetmap.josm.actions.JosmAction;
    1917import org.openstreetmap.josm.plugins.mapillary.MapillaryAbstractImage;
    20 import org.openstreetmap.josm.plugins.mapillary.MapillaryLayer;
    2118import org.openstreetmap.josm.plugins.mapillary.MapillaryPlugin;
    2219import org.openstreetmap.josm.plugins.mapillary.history.MapillaryRecord;
    2320import org.openstreetmap.josm.plugins.mapillary.history.commands.CommandImport;
     21import org.openstreetmap.josm.plugins.mapillary.utils.ImageUtil;
    2422import org.openstreetmap.josm.plugins.mapillary.utils.MapillaryUtils;
    2523import org.openstreetmap.josm.tools.Shortcut;
     
    6058    chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
    6159    chooser.setAcceptAllFileFilterUsed(false);
    62     chooser.addChoosableFileFilter(new FileNameExtensionFilter("images", "jpg", "jpeg", "png"));
     60    chooser.addChoosableFileFilter(ImageUtil.IMAGE_FILE_FILTER);
    6361    chooser.setMultiSelectionEnabled(true);
    6462    if (chooser.showOpenDialog(Main.parent) == JFileChooser.APPROVE_OPTION) {
     
    6664      for (File file : chooser.getSelectedFiles()) {
    6765        Main.pref.put("mapillary.start-directory", file.getParent());
    68         MapillaryLayer.getInstance();
    69         if (file.isDirectory()) {
    70           if (file.listFiles() == null)
    71             continue;
    72           for (File innerFile : file.listFiles()) {
    73             String extension = MapillaryUtils.getExtension(innerFile);
    74             try {
    75               if ("jpg".equals(extension) || "jpeg".equals(extension))
    76                 images.add(MapillaryUtils.readJPG(innerFile));
    77               else if ("png".equals(extension))
    78                 images.add(MapillaryUtils.readPNG(innerFile));
    79             } catch (ImageReadException | IOException | NullPointerException e1) {
    80               Main.error(e1);
    81             }
    82           }
    83         } else {
    84           String extension = MapillaryUtils.getExtension(file);
    85           if ("jpg".equals(extension) || "jpeg".equals(extension)) {
    86             try {
    87               images.add(MapillaryUtils.readJPG(file));
    88             } catch (ImageReadException ex) {
    89               Main.error(ex);
    90             } catch (IOException ex) {
    91               Main.error(ex);
    92             }
    93           } else if (".png".equals(file.getPath().substring(file.getPath().length() - 4))) {
    94             images.add(MapillaryUtils.readPNG(file));
    95           }
     66        try {
     67          images.addAll(ImageUtil.readImagesFrom(
     68              file,
     69              Main.map.mapView.getProjection().eastNorth2latlon(Main.map.mapView.getCenter())
     70          ));
     71        } catch (IOException e) {
     72          Main.error("Could not read image(s) from "+file.getAbsolutePath());
    9673        }
    9774      }
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/actions/MapillaryImportIntoSequenceAction.java

    r31986 r32034  
    1515
    1616import javax.swing.JFileChooser;
    17 import javax.swing.filechooser.FileNameExtensionFilter;
    1817
    19 import org.apache.commons.imaging.ImageReadException;
    2018import org.openstreetmap.josm.Main;
    2119import org.openstreetmap.josm.actions.JosmAction;
     
    2523import org.openstreetmap.josm.plugins.mapillary.history.MapillaryRecord;
    2624import org.openstreetmap.josm.plugins.mapillary.history.commands.CommandImport;
     25import org.openstreetmap.josm.plugins.mapillary.utils.ImageUtil;
    2726import org.openstreetmap.josm.plugins.mapillary.utils.MapillaryUtils;
    2827import org.openstreetmap.josm.tools.Shortcut;
    29 
    30 import org.openstreetmap.josm.plugins.mapillary.MapillaryLayer;
    3128
    3229/**
     
    6562    chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
    6663    chooser.setAcceptAllFileFilterUsed(false);
    67     chooser.addChoosableFileFilter(new FileNameExtensionFilter("images", "jpg", "jpeg"));
     64    chooser.addChoosableFileFilter(ImageUtil.IMAGE_FILE_FILTER);
    6865    chooser.setMultiSelectionEnabled(true);
    6966
    7067    if (chooser.showOpenDialog(Main.parent) == JFileChooser.APPROVE_OPTION) {
    7168      for (File file : chooser.getSelectedFiles()) {
    72         if (file == null)
    73           break;
    7469        Main.pref.put("mapillary.start-directory", file.getParent());
    75         MapillaryLayer.getInstance();
    76         if (file.isDirectory()) {
    77           for (File file2 : file.listFiles()) {
    78             String extension = MapillaryUtils.getExtension(file2);
    79             try {
    80               if ("jpg".equals(extension) || "jpeg".equals(extension))
    81                 MapillaryUtils.readJPG(file2, true);
    82             } catch (ImageReadException | NullPointerException | IOException e) {
    83               Main.error(e);
    84             }
    85           }
    86         } else {
    87           String extension = MapillaryUtils.getExtension(file);
    88           if ("jpg".equals(extension) || "jpeg".equals(extension)) {
    89             try {
    90               this.images.add(MapillaryUtils.readJPG(file, true));
    91             } catch (ImageReadException ex) {
    92               Main.error(ex);
    93             } catch (IOException ex) {
    94               Main.error(ex);
    95             } catch (IllegalArgumentException ex) {
    96               // Ignored image.
    97             }
    98           }
     70        try {
     71          images.addAll(ImageUtil.readImagesFrom(
     72              file,
     73              Main.map.mapView.getProjection().eastNorth2latlon(Main.map.mapView.getCenter())
     74          ));
     75        } catch (IOException e) {
     76          Main.error("Could not read image(s) from "+file.getAbsolutePath());
    9977        }
    10078      }
  • applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/utils/MapillaryUtils.java

    r32033 r32034  
    55
    66import java.awt.Desktop;
    7 import java.awt.Point;
    8 import java.awt.Rectangle;
    9 import java.awt.geom.Area;
    10 import java.io.File;
    117import java.io.IOException;
    128import java.net.URISyntaxException;
     
    2117import javax.swing.SwingUtilities;
    2218
    23 import org.apache.commons.imaging.ImageReadException;
    24 import org.apache.commons.imaging.Imaging;
    25 import org.apache.commons.imaging.common.ImageMetadata;
    2619import org.apache.commons.imaging.common.RationalNumber;
    27 import org.apache.commons.imaging.formats.jpeg.JpegImageMetadata;
    28 import org.apache.commons.imaging.formats.tiff.TiffField;
    29 import org.apache.commons.imaging.formats.tiff.constants.ExifTagConstants;
    3020import org.apache.commons.imaging.formats.tiff.constants.GpsTagConstants;
    3121import org.openstreetmap.josm.Main;
    3222import org.openstreetmap.josm.data.Bounds;
    3323import org.openstreetmap.josm.data.coor.LatLon;
    34 import org.openstreetmap.josm.gui.MapView;
    3524import org.openstreetmap.josm.plugins.mapillary.MapillaryAbstractImage;
    3625import org.openstreetmap.josm.plugins.mapillary.MapillaryData;
    37 import org.openstreetmap.josm.plugins.mapillary.MapillaryImportedImage;
    3826import org.openstreetmap.josm.plugins.mapillary.MapillaryLayer;
    3927import org.openstreetmap.josm.plugins.mapillary.MapillarySequence;
     
    165153
    166154  /**
    167    * Returns the extension of a {@link File} object.
    168    *
    169    * @param file The {@link File} object whose extension is going to be returned.
    170    * @return A {@code String} object containing the extension in lowercase.
    171    */
    172   public static String getExtension(File file) {
    173     if (file.isDirectory())
    174       throw new IllegalArgumentException("The file is a directory");
    175     int k = file.getName().lastIndexOf('.');
    176     if (k > 0) {
    177       return file.getName().substring(k + 1).toLowerCase();
    178     }
    179     throw new IllegalArgumentException("Error parsing the extension");
    180   }
    181 
    182   /**
    183155   * Joins two images into the same sequence.
    184156   *
     
    213185    if (Main.main != null)
    214186      MapillaryData.dataUpdated();
    215   }
    216 
    217   /**
    218    * Reads a JPG pictures that contains the needed GPS information (position and
    219    * direction) and creates a new icon in that position.
    220    *
    221    * @param file The file where the picture is located.
    222    * @return The imported image.
    223    * @throws ImageReadException If the file isn't an image.
    224    * @throws IOException        If the file doesn't have the valid metadata.
    225    */
    226   public static MapillaryImportedImage readJPG(File file)
    227           throws IOException, ImageReadException {
    228     return readJPG(file, false);
    229   }
    230 
    231   /**
    232    * Reads a JPG pictures that contains the needed GPS information (position and
    233    * direction) and creates a new icon in that position.
    234    *
    235    * @param file            The {@link File} where the picture is located.
    236    * @param exceptionNoTags {@code true} if an exception must be thrown if the image doesn't
    237    *                        have all the needed EXIF tags; {@code false} returns an image in
    238    *                        the center of the screen.
    239    * @return The imported image, whose data has been extracted from the
    240    * picture's metadata.
    241    * @throws ImageReadException       If the {@link File} isn't an image.
    242    * @throws IOException              If the {@link File} doesn't have the valid metadata.
    243    * @throws IllegalArgumentException if exceptionNoTags is set to {@code true} and the image doesn't
    244    *                                  have the needed EXIF tags.
    245    */
    246   public static MapillaryImportedImage readJPG(File file,
    247                                                boolean exceptionNoTags) throws IOException, ImageReadException {
    248     final ImageMetadata metadata = Imaging.getMetadata(file);
    249     if (metadata instanceof JpegImageMetadata) {
    250       final JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;
    251       final TiffField lat_ref = jpegMetadata.findEXIFValueWithExactMatch(
    252               GpsTagConstants.GPS_TAG_GPS_LATITUDE_REF);
    253       final TiffField lat = jpegMetadata
    254               .findEXIFValueWithExactMatch(GpsTagConstants.GPS_TAG_GPS_LATITUDE);
    255       final TiffField lon_ref = jpegMetadata.findEXIFValueWithExactMatch(
    256               GpsTagConstants.GPS_TAG_GPS_LONGITUDE_REF);
    257       final TiffField lon = jpegMetadata
    258               .findEXIFValueWithExactMatch(GpsTagConstants.GPS_TAG_GPS_LONGITUDE);
    259       final TiffField ca = jpegMetadata.findEXIFValueWithExactMatch(
    260               GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION);
    261       final TiffField datetimeOriginal = jpegMetadata
    262               .findEXIFValueWithExactMatch(
    263                       ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL);
    264       if (lat_ref == null || lat == null || lon == null || lon_ref == null) {
    265         if (exceptionNoTags) {
    266           throw new IllegalArgumentException("The image doesn't have the needed EXIF tags.");
    267         }
    268         return readNoTags(file);
    269       }
    270       double latValue = 0;
    271       double lonValue = 0;
    272       double caValue = 0;
    273       if (lat.getValue() instanceof RationalNumber[])
    274         latValue = MapillaryUtils.degMinSecToDouble(
    275                 (RationalNumber[]) lat.getValue(), lat_ref.getValue().toString());
    276       if (lon.getValue() instanceof RationalNumber[])
    277         lonValue = MapillaryUtils.degMinSecToDouble(
    278                 (RationalNumber[]) lon.getValue(), lon_ref.getValue().toString());
    279       if (ca != null && ca.getValue() instanceof RationalNumber)
    280         caValue = ((RationalNumber) ca.getValue()).doubleValue();
    281       if (datetimeOriginal != null) {
    282         return new MapillaryImportedImage(new LatLon(latValue, lonValue), caValue, file, datetimeOriginal.getStringValue());
    283       }
    284       return new MapillaryImportedImage(new LatLon(latValue, lonValue), caValue, file);
    285     }
    286     throw new IllegalStateException("Invalid format.");
    287   }
    288 
    289   /**
    290    * Reads a image file that doesn't contain the needed GPS information. And
    291    * creates a new icon in the middle of the map.
    292    *
    293    * @param file The file where the image is located.
    294    * @return The imported image.
    295    */
    296   public static MapillaryImportedImage readNoTags(File file) {
    297     return readNoTags(file, Main.map.mapView.getProjection()
    298             .eastNorth2latlon(Main.map.mapView.getCenter()));
    299   }
    300 
    301   /**
    302    * Reads a image file that doesn't contain the needed GPS information. And
    303    * creates a new icon in the middle of the map.
    304    *
    305    * @param file The file where the image is located.
    306    * @param pos  A {@link LatLon} object indicating the position in the map where
    307    *             the image must be set.
    308    * @return The imported image.
    309    */
    310   public static MapillaryImportedImage readNoTags(File file, LatLon pos) {
    311     ImageMetadata metadata = null;
    312     try {
    313       metadata = Imaging.getMetadata(file);
    314     } catch (IOException e) {
    315       Main.error(e);
    316     } catch (ImageReadException e) {
    317       Main.error(e);
    318     }
    319     if (metadata instanceof JpegImageMetadata) {
    320       final JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;
    321       final TiffField datetimeOriginal = jpegMetadata
    322               .findEXIFValueWithExactMatch(
    323                       ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL);
    324       if (datetimeOriginal == null) {
    325         return new MapillaryImportedImage(pos, 0, file);
    326       }
    327       try {
    328         return new MapillaryImportedImage(pos, 0, file, datetimeOriginal.getStringValue());
    329       } catch (ImageReadException e) {
    330         Main.error(e);
    331       }
    332     }
    333     return new MapillaryImportedImage(pos, 0, file);
    334   }
    335 
    336   /**
    337    * Reads an image in PNG format.
    338    *
    339    * @param file The file where the image is located.
    340    * @return The imported image.
    341    */
    342   public static MapillaryImportedImage readPNG(File file) {
    343     return readNoTags(file);
    344187  }
    345188
Note: See TracChangeset for help on using the changeset viewer.