Ignore:
Timestamp:
2021-03-02T13:53:11+01:00 (3 years ago)
Author:
Bjoeni
Message:

fix #20341 - support more image formats and writing metadata to TIFF files

Location:
applications/editors/josm/plugins/photo_geotagging/src/org/openstreetmap/josm/plugins/photo_geotagging
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/photo_geotagging/src/org/openstreetmap/josm/plugins/photo_geotagging/ExifGPSTagger.java

    r34542 r35715  
    2323import org.apache.commons.imaging.formats.tiff.TiffImageMetadata;
    2424import org.apache.commons.imaging.formats.tiff.constants.GpsTagConstants;
     25import org.apache.commons.imaging.formats.tiff.write.TiffImageWriterLossy;
    2526import org.apache.commons.imaging.formats.tiff.write.TiffOutputDirectory;
    2627import org.apache.commons.imaging.formats.tiff.write.TiffOutputSet;
     
    2930    /**
    3031     * Set the GPS values in JPEG EXIF metadata.
    31      * This is taken from one of the examples of the sanselan project.
     32     * This is based on one of the examples of the sanselan project.
    3233     *
    33      * @param jpegImageFile A source image file.
     34     * @param imageFile A source image file.
    3435     * @param dst The output file.
    3536     * @param lat latitude
     
    4142     * @throws IOException in case of I/O error
    4243     */
    43     public static void setExifGPSTag(File jpegImageFile, File dst, double lat, double lon, Date gpsTime, Double speed, Double ele, Double imgDir) throws IOException {
     44    public static void setExifGPSTag(File imageFile, File dst, double lat, double lon, Date gpsTime, Double speed, Double ele, Double imgDir) throws IOException {
    4445        try {
    45             setExifGPSTagWorker(jpegImageFile, dst, lat, lon, gpsTime, speed, ele, imgDir);
     46            setExifGPSTagWorker(imageFile, dst, lat, lon, gpsTime, speed, ele, imgDir);
    4647        } catch (ImageReadException ire) {
    4748            throw new IOException(tr("Read error: "+ire), ire);
     
    5152    }
    5253
    53     public static void setExifGPSTagWorker(File jpegImageFile, File dst, double lat, double lon, Date gpsTime, Double speed, Double ele, Double imgDir)
     54    public static void setExifGPSTagWorker(File imageFile, File dst, double lat, double lon, Date gpsTime, Double speed, Double ele, Double imgDir)
    5455            throws IOException, ImageReadException, ImageWriteException {
     56
    5557        TiffOutputSet outputSet = null;
     58        ImageMetadata metadata = Imaging.getMetadata(imageFile);
    5659
    57         ImageMetadata metadata = Imaging.getMetadata(jpegImageFile);
    58         JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;
    59         if (null != jpegMetadata) {
    60             TiffImageMetadata exif = jpegMetadata.getExif();
    61 
     60        if (metadata instanceof JpegImageMetadata) {
     61            TiffImageMetadata exif = ((JpegImageMetadata) metadata).getExif();
    6262            if (null != exif) {
    6363                outputSet = exif.getOutputSet();
    6464            }
     65        } else if (metadata instanceof TiffImageMetadata) {
     66            outputSet = ((TiffImageMetadata) metadata).getOutputSet();
    6567        }
    6668
     
    9799            // not fail if the tag does not exist).
    98100            gpsDirectory.removeField(GpsTagConstants.GPS_TAG_GPS_TIME_STAMP);
    99             gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_TIME_STAMP, 
     101            gpsDirectory.add(GpsTagConstants.GPS_TAG_GPS_TIME_STAMP,
    100102                    RationalNumber.valueOf(hour),
    101103                    RationalNumber.valueOf(minute),
     
    145147
    146148        try (BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(dst))) {
    147             new ExifRewriter().updateExifMetadataLossless(jpegImageFile, os, outputSet);
     149            if (metadata instanceof JpegImageMetadata) {
     150                new ExifRewriter().updateExifMetadataLossless(imageFile, os, outputSet);
     151            } else if (metadata instanceof TiffImageMetadata) {
     152                new TiffImageWriterLossy().write(os, outputSet);
     153            }
    148154        }
    149155    }
  • applications/editors/josm/plugins/photo_geotagging/src/org/openstreetmap/josm/plugins/photo_geotagging/GeotaggingAction.java

    r35499 r35715  
    33
    44import static org.openstreetmap.josm.tools.I18n.tr;
    5 
     5import static org.openstreetmap.josm.tools.I18n.trn;
     6
     7import java.awt.Color;
    68import java.awt.Component;
    79import java.awt.Dimension;
     
    3335import javax.swing.UIManager;
    3436
     37import org.apache.commons.io.FilenameUtils;
    3538import org.openstreetmap.josm.gui.ExtendedDialog;
    3639import org.openstreetmap.josm.gui.MainApplication;
     
    7073
    7174        final List<ImageEntry> images = new ArrayList<>();
     75        int notSupportedFilesCount = 0;
     76        String notSupportedName = null;
     77        boolean hasTiff = false;
     78
     79        final JPanel cont = new JPanel(new GridBagLayout());
     80        cont.add(new JLabel(tr("Write position information into the exif header of the following files:")), GBC.eol());
     81
     82        DefaultListModel<String> listModel = new DefaultListModel<>();
     83        DecimalFormat dFormatter = new DecimalFormat("###0.000000");
     84
    7285        for (ImageEntry e : layer.getImages()) {
    7386             /* Only write lat/lon to the file, if the position is known and
    7487                the GPS data changed. */
    7588            if (e.getPos() != null && e.hasNewGpsData()) {
    76                 images.add(e);
    77             }
    78         }
    79 
    80         final JPanel cont = new JPanel(new GridBagLayout());
    81         cont.add(new JLabel(tr("Write position information into the exif header of the following files:")), GBC.eol());
    82 
    83         DefaultListModel<String> listModel = new DefaultListModel<>();
    84         DecimalFormat dFormatter = new DecimalFormat("###0.000000");
    85         for (ImageEntry e : images) {
    86             listModel.addElement(e.getFile().getAbsolutePath()+
    87                 " ("+dFormatter.format(e.getPos().lat())+","+dFormatter.format(e.getPos().lon())+")");
     89                String pth = e.getFile().getAbsolutePath();
     90                switch (FilenameUtils.getExtension(pth).toLowerCase()) {
     91                    case "tif":
     92                    case "tiff":
     93                        hasTiff = true;
     94                        // fall through (this comment makes the compiler happy)
     95                    case "jpg":
     96                    case "jpeg":
     97                        images.add(e);
     98                        listModel.addElement(pth + " (" + dFormatter.format(e.getPos().lat()) + ","
     99                                + dFormatter.format(e.getPos().lon()) + ")");
     100                        break;
     101                    default:
     102                        notSupportedFilesCount++;
     103                        if (notSupportedName == null) {
     104                            notSupportedName = e.getFile().getName();
     105                        }
     106                        break;
     107                }
     108            }
    88109        }
    89110
     
    93114        scroll.setPreferredSize(new Dimension(900, 250));
    94115        cont.add(scroll, GBC.eol().fill(GBC.BOTH));
     116
     117        if (notSupportedFilesCount > 0) {
     118            JLabel warn = new JLabel(trn("The file \"{0}\" can not be updated. Only JPEG and TIFF images are supported.",
     119                    "{1} files can not be updated. Only JPEG and TIFF images are supported.", notSupportedFilesCount, notSupportedName, Integer.toString(notSupportedFilesCount)));
     120            warn.setForeground(Color.RED);
     121            cont.add(warn, GBC.eol());
     122        }
     123
     124        if (hasTiff) {
     125            JLabel warn = new JLabel(tr("Warning: Some metadata in TIFF files may be lost. Always keep a backup!"));
     126            warn.setForeground(Color.RED);
     127            cont.add(warn, GBC.eol());
     128        }
    95129
    96130        final JPanel settingsPanel = new JPanel(new GridBagLayout());
     
    334368            // for getting a unique file name, we use UUID.randomUUID()
    335369            do {
    336                 fileTmp = new File(file.getParentFile(), "img" + UUID.randomUUID() + ".jpg");
     370                fileTmp = new File(file.getParentFile(), "img" + UUID.randomUUID() + ".tmp");
    337371            } while (fileTmp.exists());
    338372            if (debug) {
  • applications/editors/josm/plugins/photo_geotagging/src/org/openstreetmap/josm/plugins/photo_geotagging/GeotaggingPlugin.java

    r22551 r35715  
    88/**
    99 * This plugin is used to write latitude and longitude information
    10  * to the EXIF header of jpg files.
     10 * to the EXIF header of jpg and tiff files.
    1111 * It extends the core geoimage feature of JOSM by adding a new entry
    1212 * to the right click menu of any image layer.
Note: See TracChangeset for help on using the changeset viewer.