大规模迁移 EXIF GPS 数据(又名逃离 iPhoto)

大规模迁移 EXIF GPS 数据(又名逃离 iPhoto)

我正在尝试将我的照片库(超过 12000 张)移出 iPhoto 以用于 Adob​​e Lightroom,并希望使用 iPhoto 的应用内功能将我添加到照片中的 GPS 数据包含在内(此数据存储在 Apple 的专有数据库中,而不是照片本身的元数据)。我可以通过导出来传输数据,但我想要 iPhoto 不会修改的原始 RAW 文件。所以我提出的解决方案是:

1) 将所有原始 RAW 照片导出到按事件名称排序的目录树中。2) 将所有照片导出为 JPEG,并将 GPS 数据嵌入 EXIF 数据中(iPhoto 可以做到)。3) 使用“exiftool”从 jpeg 中提取 GPS 数据并将其复制到匹配的原始文件中。

我可以使用以下命令一次对一张照片进行 #3 操作:

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

Photos-Mod 文件包含来自 iPhoto 的 GPS 数据,而 Photos-Orig 没有。除了主目录名称和文件扩展名外,目录树和文件名将完全相同(在某些情况下,我的原始文件也是 jpeg)。我希望有一个好方法可以编写一个脚本,可以在 Photos-Mod 父目录中的 iPhoto 修改文件上运行 exiftool,并将 GPS 数据移动到 Photos-Orig 父目录中匹配文件名和事件目录的原始文件。

我只是没有编写脚本的技能。任何帮助都非常感谢。

答案1

该问题由以下几个部分组成:

  1. 查找Photos-Mod目录下的所有照片
  2. 找到下方的每一张对应的照片Photos-Orig
  3. exiftools使用正确的参数调用

查找所有照片

通过使用像这样的 glob 表达式,这很容易~/Photo-Mod/*/*

找到对应的照片

给定一个完整路径,我们可以用 替换Photo-ModPhoto-Orig我们进一步将文件扩展名更改为 ,*以便我们有另一个 glob 表达式。如果此 glob 不匹配任何文件,我们将打印一条错误消息,但只需继续即可。

现在调用 exiftools 很容易。

Bash 解决方案

快速回顾一下 Bash 语法:

  • Foreach 循环:

    for variable in EXPR; do
      COMMANDS;
    done
    
  • 如果别的:

    if COND; then
      COMMANDS;
    else
      COMMANDS;
    fi
    
  • Filetests:([ -e $file ]测试-e文件是否存在)

  • 变量赋值:var=$(COMMANDS)

我们可以通过使用正则表达式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

删除所有换行符后即可直接在命令行上运行。您还可以将其放入 shell 脚本中,然后从那里调用它。

笔记:使用类似的 glob 表达式进行测试,并且exiftools在 GNU bash 下没有进行测试)

Perl 解决方案

Perl 语法快速介绍:

  • Foreach 循环:

    for my $variable (LIST) {
      COMMANDS
    }
    
  • 如果别的:

    if (COND) {
      COMMANDS
    } else {
      COMMANDS
    }
    
  • 文件测试:-e $filename

  • 变量赋值:my $var = EXPR;

正则表达式是语言的一部分,可以通过 来应用$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";
  }
}

您可以将代码转储到文件中,然后使用 调用它perl script.pl。或者您可以使用此处的文档:

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

笔记:Perl 脚本已在 Linux 上使用 perls v16.3 和 v14.2 进行了测试。)

相关内容