Massenmigration von EXIF-GPS-Daten (auch bekannt als Escape von iPhoto)

1185
Ben Gross

Ich versuche, meine Fotobibliothek (über 12.000) für die Verwendung in Adobe Lightroom aus iPhoto zu entfernen und möchte die GPS-Daten, die ich den Fotos hinzugefügt habe, mithilfe der In-App-Funktion von iPhoto hinzufügen (Diese Daten werden im proprietären Apple-System gespeichert.) Datenbank, nicht als Metadaten im Foto selbst). Ich kann die Daten durch Exportieren übertragen, aber ich möchte, dass die ursprünglichen RAW-Dateien von iPhoto nicht geändert werden. Meine vorgeschlagene Lösung lautet also:

1) Exportieren Sie alle ursprünglichen RAW-Fotos in eine nach Ereignisnamen sortierte Verzeichnisstruktur. 2) Exportieren Sie alle Fotos als JPEG-Dateien, wobei die GPS-Daten in die EXIF-Daten eingebettet sind (wie bei iPhoto möglich). 3) Verwenden Sie "exiftool", um die GPS-Daten aus dem JPEG-Format zu ziehen und in die entsprechende Rohdatei zu kopieren.

Mit dem folgenden Befehl kann ich jeweils ein Foto Nr. 3 erstellen:

exiftool -overwrite_original_in_place -tagsFromFile ~/Photos-Mod/Event001/photo001.jpg -gps:all ~/Photos-Orig/Event001/photo001.NEF 

Die Photos-Mod-Dateien enthalten die GPS-Daten von iPhoto und Photos-Orig nicht. Der Verzeichnisbaum und die Dateinamen sind bis auf den Namen des Hauptverzeichnisses und die Dateierweiterung identisch (in manchen Fällen ist mein Original auch ein JPEG-Element). Ich hoffe, dass es eine gute Möglichkeit gibt, ein Skript zu erstellen, mit dem Exiftool mit den geänderten iPhoto-Dateien im übergeordneten Verzeichnis Photos-Mod ausgeführt werden kann, und die GPS-Daten in die Originaldatei mit übereinstimmendem Dateinamen und Ereignisverzeichnis in den Fotos verschieben -Orig übergeordnetes Verzeichnis.

Ich habe einfach keine Scripting-Fähigkeiten. Jede Hilfe hier wäre heiß.

0
Diese Frage ist ein bisschen zu weit in die Region "gib mir the codez plz", aber ich denke, ich kann Ihnen helfen, das Problem selbst zu lösen. Zunächst einige wichtige Fragen: ① Haben Sie Programmiererfahrung (falls ja, in welcher Form)? Dies hilft, auf Erklärungen abzielen. ② Können Sie garantieren, dass der einzige Unterschied zwischen den Fotopfaden darin besteht, dass `Mod` zu` Orig` wechselt und die Erweiterung von `jpg` nach` NEF`? ③ Ist die Tiefe der Fotopfade konstant oder haben einige Ereignisordner Unterordner, die besucht werden sollten? ④ Möchten Sie Perl oder Bash verwenden? amon vor 11 Jahren 0
amon, Totally "gib mir die codez plz" (sorry), aber ich werde jede Hilfe in Anspruch nehmen, die ich Ihnen beim Lösen meines Problems geben kann. Ich habe nur begrenzte Erfahrung, nur aus der Praxis. Matlab meistens und etwas Shell-Scripting (bash). Sed und Grep zum letzten Mal benutzt. Aber ich bin 10 Jahre ohne Übung. Der Unterschied wird Mod to Orig sein, wie Sie sagten, und die Erweiterung, aber einige Erweiterungen werden sich nicht ändern. (Einige werden .NEF> .jpg sein und andere werden .jpg> .jpg sein) Die Tiefe wird konstant sein. Ich organisiere als Photos-Orig / Year / Event001 / photo001.NEF Ich bin am besten mit bash vertraut, null Erfahrung mit Perl. Ben Gross vor 11 Jahren 0

1 Antwort auf die Frage

0
amon

The problem consists of the following parts:

  1. Find all photos under the Photos-Mod directory
  2. Find each corresponding photo under Photos-Orig
  3. Invoke exiftools with correct arguments

Finding all photos

This is easy by using a glob expression like ~/Photo-Mod/*/*.

Finding the corresponding photo

Given a full path, we can substitute the Photo-Mod for Photo-Orig. We further change the file extension to * so that we have another glob expression. If this glob matches no files, we print an error message, but simply carry on.

Invoking exiftools is now easy.

A Bash solution

Quick recap of Bash syntax:

  • Foreach-loops:

    for variable in EXPR; do COMMANDS; done 
  • If-else:

    if COND; then COMMANDS; else COMMANDS; fi 
  • Filetests: [ -e $file ] (-e tests for existence of files)

  • variable assignments: var=$(COMMANDS).

We can use regular expressions via sed.

# There are probably more elegant ways, but I don't know much bash for mod in ~/Photo-Mod/*/*/*; do orig=$(echo $mod | sed -e 's/Photo-Mod/Photo-Orig/;s/\.[^.]*$/.*/'); orig=($orig); # Apply the glob expression, select result if [ -e $orig ]; then exiftool -overwrite_original_in_place -tagsFromFile "$mod" -gps:all "$orig"; else echo "No corresponding file for $mod found. Skipping!" >&2; fi; done 

This can be run directly on the commandline by removing all newlines. You can also put it into a shell script., and invoke it from there.

(Note: tested with similar glob expressions and without exiftools under GNU bash)

A Perl solution

Quick introduction to Perl syntax:

  • Foreach-loops:

    for my $variable (LIST) { COMMANDS } 
  • If-else:

    if (COND) { COMMANDS } else { COMMANDS } 
  • Filetests: -e $filename

  • variable assignments: my $var = EXPR;

Regular expressions are part of the language, and can be applied by $var =~ /REGEX/.

use strict; use warnings; # helps us write better scripts use autodie; # automatic error handling  for my $mod (glob '~/Photo-Mod/*/*/*') { my $orig = $mod; $orig =~ s/Photo-Mod/Photo-Orig/; $orig =~ s/\.[^.]*$/.*/; if (($orig) = glob qq("$orig")) { # implicitly tests for existence system 'exiftool', '-overwrite_original_in_place', '-tagsFromFile', $mod, '-gps:all', $orig; } else { warn "No corresponding file for $mod found. Skipping!\n"; } } 

You can dump the code in a file, then invoke it with perl script.pl. Or you can use a here-doc:

$ perl <<'END' # The code goes here END 

(Note: The Perl scripts were tested with perls v16.3 and v14.2 on Linux.)

amon, das sieht perfekt aus. Werde testen und dich wissen lassen, wie es läuft! Danke nochmal für deine Hilfe. Ben Gross vor 11 Jahren 0
Ich habe es fast mit dem Perl-Skript bekommen, denke ich. Ich habe Probleme mit den Leerzeichen in den Ereignisnamen (dh Verzeichnisnamen). Gibt es eine Möglichkeit, das zu umgehen, oder muss ich alles umbenennen? Ben Gross vor 11 Jahren 0
@BenGross Perls 'glob'-Funktion teilt das gegebene Muster im Whitespace in Submuster auf. Das Argument sollte in Anführungszeichen gesetzt werden - ich habe meinen Code entsprechend aktualisiert. Ich habe nicht genügend tiefe Kenntnisse der Parsing-Regeln, um dieselbe Korrektur in der Bash-Version vorzunehmen. amon vor 11 Jahren 0
Dein Perl-Skript funktioniert wie ein Zauber! Danke amon. Ich habe qq {} an verschiedenen Stellen im Skript ausprobiert, konnte es aber nicht zum Laufen bringen. Danke noch einmal! Ben Gross vor 11 Jahren 0