diff --git a/README-SAMPLES.md b/README-SAMPLES.md index 99391f42..7b50d3de 100644 --- a/README-SAMPLES.md +++ b/README-SAMPLES.md @@ -195,7 +195,7 @@ $ #### geotag ``` -Usage: geotag {-help|-version|-dst|-dryrun|-ascii|-verbose|-adjust value|-tz value|-delta value}+ path+ +Usage: geotag {-help|-version|-dst|-dryrun|-ascii|-remove|-verbose|-adjust value|-tz value|-delta value}+ path+ ``` Geotag reads one or more GPX files and adds GPS Tages to images. _Code: [geotag.cpp](samples/geotag.cpp)_ @@ -208,6 +208,7 @@ If the path is a directory, geotag will read all the files in the directory. It | -dst | Apply 1 hour adjustment for daylight saving time. | | -dryrun | Read arguments and print report. Does not modify images. | | -verbose | Report progress. | +| -remove | Removes GPS tags from images. | | -adjust value | Add/subtract time from image data. | | -tz value | Specify time zone. For example PST = -8:00 | | -delta value | Correction between Image DataTime and GPS time. | @@ -643,4 +644,4 @@ Read an XMP packet from a file, parse and re-serialize it. Robin Mills
robin@clanmills.com
-Revised: 2019-06-20 \ No newline at end of file +Revised: 2020-05-01 \ No newline at end of file diff --git a/samples/geotag.cpp b/samples/geotag.cpp index 84061f52..0e806d35 100644 --- a/samples/geotag.cpp +++ b/samples/geotag.cpp @@ -87,6 +87,7 @@ public: bool dst; bool dryrun; bool ascii; + bool remove; Options() { @@ -96,6 +97,7 @@ public: dst = false; dryrun = false; ascii = false; + remove = false; } virtual ~Options() {} ; @@ -113,6 +115,7 @@ enum // keyword indices , kwDST , kwDRYRUN , kwASCII +, kwREMOVE , kwVERBOSE , kwADJUST , kwTZ @@ -790,6 +793,7 @@ int main(int argc,const char* argv[]) keywords[kwADJUST ] = "adjust"; keywords[kwTZ ] = "tz"; keywords[kwDELTA ] = "delta"; + keywords[kwREMOVE ] = "remove"; map shorts; shorts["-?"] = "-help"; @@ -803,6 +807,7 @@ int main(int argc,const char* argv[]) shorts["-s"] = "-delta"; shorts["-X"] = "-dryrun"; shorts["-a"] = "-ascii"; + shorts["-r"] = "-remove"; Options options ; options.help = sina(keywords[kwHELP ],argv) || argc < 2; @@ -811,6 +816,7 @@ int main(int argc,const char* argv[]) options.version = sina(keywords[kwVERSION],argv); options.dst = sina(keywords[kwDST ],argv); options.ascii = sina(keywords[kwASCII ],argv); + options.remove = sina(keywords[kwASCII ],argv); for ( int i = 1 ; !result && i < argc ; i++ ) { const char* arg = argv[i++]; @@ -831,6 +837,7 @@ int main(int argc,const char* argv[]) case kwDRYRUN : options.dryrun = true ; break; case kwVERBOSE : options.verbose = true ; break; case kwASCII : options.ascii = true ; break; + case kwREMOVE : options.remove = true ; break; case kwTZ : Position::tz_ = parseTZ(value);break; case kwADJUST : Position::adjust_ = ivalue;break; case kwDELTA : Position::deltaMax_ = ivalue;break; @@ -881,8 +888,8 @@ int main(int argc,const char* argv[]) s-= m*60 ; printf("tz,dst,adjust = %d,%d,%d total = %dsecs (= %d:%d:%d)\n",t,d,a,A,h,m,s); } -/* - if ( options.verbose ) { + + if ( options.verbose && gTimeDict.size() ) { printf("Time Dictionary\n"); for ( TimeDict_i it = gTimeDict.begin() ; it != gTimeDict.end() ; it++ ) { std::string sTime = getExifTime(it->first); @@ -894,7 +901,10 @@ int main(int argc,const char* argv[]) printf("%s %s\n",sTime.c_str(), sPos.c_str()); } } -*/ + + if ( !gTimeDict.size() && gFiles.size() && !options.remove ) { + printf("nothing in time dictionary!\n"); + } for ( size_t p = 0 ; p < gFiles.size() ; p++ ) { std::string path = gFiles[p] ; std::string stamp ; @@ -905,8 +915,22 @@ int main(int argc,const char* argv[]) if ( image.get() ) { image->readMetadata(); Exiv2::ExifData& exifData = image->exifData(); + + // if asked to remove, cycle the metadata and remove GPSInfo + // you can remove and geotag in the same run + // this is very useful when the TZ is incorrectly set to "clean" GPS before writing new data + if ( options.remove ) { + for (Exiv2::ExifData::iterator pos = exifData.begin(); pos != exifData.end(); ++pos) { + if ( pos->groupName() == "GPSInfo" ) { + if ( options.verbose ) { + std::cout << "remove: " << pos->key() << std::endl; + } + if ( !options.dryrun ) exifData.erase(pos); + } + } + } if ( pPos ) { - exifData["Exif.GPSInfo.GPSProcessingMethod" ] = "65 83 67 73 73 0 0 0 72 89 66 82 73 68 45 70 73 88"; // ASCII HYBRID-FIX + exifData["Exif.GPSInfo.GPSProcessingMethod" ] = "charset=Ascii HYBRID-FIX"; exifData["Exif.GPSInfo.GPSVersionID" ] = "2 2 0 0"; exifData["Exif.GPSInfo.GPSMapDatum" ] = "WGS-84"; @@ -924,7 +948,9 @@ int main(int argc,const char* argv[]) printf("%s %s % 2d\n",path.c_str(),pPos->toString().c_str(),pPos->delta()); } else { - printf("%s *** not in time dict ***\n",path.c_str()); + if ( gTimeDict.size() ) { + printf("%s *** not in time dict ***\n",path.c_str()); + } } if ( !options.dryrun ) image->writeMetadata(); } diff --git a/test/data/geotag-test.out b/test/data/geotag-test.out index 0d49855c..56af4b39 100644 --- a/test/data/geotag-test.out +++ b/test/data/geotag-test.out @@ -23,5 +23,5 @@ Exif.GPSInfo.GPSAltitudeRef Byte 1 Below sea level Exif.GPSInfo.GPSAltitude Rational 1 14.3 m Exif.GPSInfo.GPSTimeStamp Rational 3 09:54:28 Exif.GPSInfo.GPSMapDatum Ascii 7 WGS-84 -Exif.GPSInfo.GPSProcessingMethod Undefined 58 65 83 67 73 73 0 0 0 72 89 66 82 73 68 45 70 73 88 +Exif.GPSInfo.GPSProcessingMethod Undefined 18 HYBRID-FIX Exif.GPSInfo.GPSDateStamp Ascii 20 2008:05:08 09:54:28