Changeset 35738 in osm for applications/editors


Ignore:
Timestamp:
2021-04-25T18:09:26+02:00 (3 years ago)
Author:
Bjoeni
Message:

fix #11757

  • Allow user to try tagging images using the lossy approach in case of ExifOverflowException
  • Automatically restore backup file in case something goes wrong
Location:
applications/editors/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

    r35715 r35738  
    4040     * @param ele elevation - can be null if not available
    4141     * @param imgDir image direction in degrees (0..360) - can be null if not available
     42     * @param lossy whether to use lossy approach when writing metadata (overwriting unknown tags)
    4243     * @throws IOException in case of I/O error
    4344     */
    44     public static void setExifGPSTag(File imageFile, File dst, double lat, double lon, Date gpsTime, Double speed, Double ele, Double imgDir) throws IOException {
     45    public static void setExifGPSTag(File imageFile, File dst, double lat, double lon, Date gpsTime, Double speed, Double ele, Double imgDir, boolean lossy) throws IOException {
    4546        try {
    46             setExifGPSTagWorker(imageFile, dst, lat, lon, gpsTime, speed, ele, imgDir);
     47            setExifGPSTagWorker(imageFile, dst, lat, lon, gpsTime, speed, ele, imgDir, lossy);
    4748        } catch (ImageReadException ire) {
    4849            throw new IOException(tr("Read error: "+ire), ire);
     
    5253    }
    5354
    54     public static void setExifGPSTagWorker(File imageFile, File dst, double lat, double lon, Date gpsTime, Double speed, Double ele, Double imgDir)
     55    public static void setExifGPSTagWorker(File imageFile, File dst, double lat, double lon, Date gpsTime, Double speed, Double ele, Double imgDir, boolean lossy)
    5556            throws IOException, ImageReadException, ImageWriteException {
    5657
     
    148149        try (BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(dst))) {
    149150            if (metadata instanceof JpegImageMetadata) {
    150                 new ExifRewriter().updateExifMetadataLossless(imageFile, os, outputSet);
     151                if (lossy) {
     152                    new ExifRewriter().updateExifMetadataLossy(imageFile, os, outputSet);
     153                } else {
     154                    new ExifRewriter().updateExifMetadataLossless(imageFile, os, outputSet);
     155                }
    151156            } else if (metadata instanceof TiffImageMetadata) {
    152157                new TiffImageWriterLossy().write(os, outputSet);
  • applications/editors/josm/plugins/photo_geotagging/src/org/openstreetmap/josm/plugins/photo_geotagging/GeotaggingAction.java

    r35726 r35738  
    3535import javax.swing.UIManager;
    3636
     37import org.apache.commons.imaging.formats.jpeg.exif.ExifRewriter;
    3738import org.apache.commons.io.FilenameUtils;
    3839import org.openstreetmap.josm.gui.ExtendedDialog;
     
    210211        private boolean canceled = false;
    211212        private Boolean override_backup = null;
     213        private boolean lossy = false;
    212214
    213215        private File fileFrom;
     
    258260            if (canceled) return;
    259261            ExifGPSTagger.setExifGPSTag(fileFrom, fileTo, e.getPos().lat(), e.getPos().lon(),
    260                     e.getGpsTime(), e.getSpeed(), e.getElevation(), e.getExifImgDir());
     262                    e.getGpsTime(), e.getSpeed(), e.getElevation(), e.getExifImgDir(), lossy);
     263            lossy = false;
    261264
    262265            if (mTime != null) {
     
    287290                } catch (final IOException ioe) {
    288291                    ioe.printStackTrace();
     292                    restoreFile();
    289293                    try {
    290294                        SwingUtilities.invokeAndWait(() -> {
    291295                            ExtendedDialog dlg = new ExtendedDialog(progressMonitor.getWindowParent(), tr("Error"), new String[] {tr("Abort"), tr("Retry"), tr("Ignore")});
    292                             dlg.setIcon(JOptionPane.ERROR_MESSAGE);
    293296                            dlg.setButtonIcons("cancel", "dialogs/refresh", "dialogs/next");
    294297                            String msg;
     
    298301                                msg = ioe.toString();
    299302                            }
    300                             dlg.setContent(tr("Unable to process file ''{0}'':", e.getFile().toString()) + "<br/>" + msg);
     303                            boolean tmpLossy = false;
     304                            if (!lossy && ioe.getCause() instanceof ExifRewriter.ExifOverflowException) {
     305                                tmpLossy = true;
     306                                dlg.setIcon(JOptionPane.WARNING_MESSAGE);
     307                                dlg.setContent(tr(
     308                                        "The GPS tag could not be added to the file \"{0}\" because there is not enough free space in the EXIF section.<br>"
     309                                                + "This can likely be fixed by rewriting the entire EXIF section, however some metadata may get lost in the process.<br><br>"
     310                                                + "Would you like to try again using the lossy approach?",
     311                                        e.getFile().getName()));
     312                                dlg.setDefaultButton(2);
     313                            } else {
     314                                dlg.setIcon(JOptionPane.ERROR_MESSAGE);
     315                                dlg.setContent(tr("Unable to process file ''{0}'':", e.getFile().toString()) + "<br/>" + msg);
     316                                dlg.setDefaultButton(3);
     317                            }
    301318                            dlg.showDialog();
    302319                            switch (dlg.getValue()) {
    303320                                case 2:  // retry
    304321                                    currentIndex--;
     322                                    lossy = tmpLossy;
    305323                                    break;
    306324                                case 3:  // continue
     
    417435        }
    418436
     437        private void restoreFile() {
     438            if (fileFrom != null && fileFrom.exists()) {
     439                if (fileTo != null && fileTo.exists()) {
     440                    fileTo.delete();
     441                }
     442                fileFrom.renameTo(fileTo);
     443            }
     444        }
     445
    419446        private void cleanupFiles() throws IOException {
    420447            if (fileDelete != null) {
  • applications/editors/josm/plugins/photo_geotagging/test/unit/org/openstreetmap/josm/plugins/photo_geotagging/ExifGPSTaggerTest.java

    r32392 r35738  
    2525
    2626    @Test
    27     @Ignore("To enable after https://issues.apache.org/jira/browse/IMAGING-179 is fixed")
    2827    public void testTicket11757() throws Exception {
    2928        final File in = new File(TestUtils.getTestDataRoot(), "_DSC1234.jpg");
    30         ExifGPSTagger.setExifGPSTag(in, tempFolder.newFile(), 12, 34, new Date(), 12.34, Math.E, Math.PI);
     29        ExifGPSTagger.setExifGPSTag(in, tempFolder.newFile(), 12, 34, new Date(), 12.34, Math.E, Math.PI, true);
    3130    }
    3231
     
    4443        final File in = new File(TestUtils.getTestDataRoot(), "IMG_7250_small.JPG");
    4544        final File out = tempFolder.newFile();
    46         ExifGPSTagger.setExifGPSTag(in, out, 12, 34, new Date(), 12.34, Math.E, Math.PI);
     45        ExifGPSTagger.setExifGPSTag(in, out, 12, 34, new Date(), 12.34, Math.E, Math.PI, false);
    4746        final Process jhead = Runtime.getRuntime().exec(new String[]{"jhead", out.getAbsolutePath()});
    4847        final String stdout = new Scanner(jhead.getErrorStream()).useDelimiter("\\A").next();
Note: See TracChangeset for help on using the changeset viewer.