Я пытаюсь переместить свою библиотеку фотографий (более 12000) из iPhoto для использования в Adobe Lightroom и хотел бы добавить данные GPS, которые я добавил к фотографиям, с помощью функции iPhoto, встроенной в приложение (эти данные хранятся в частной собственности Apple база данных, а не как метаданные на самой фотографии). Я могу передать данные путем экспорта, но я хочу оригинальные файлы RAW, которые iPhoto не будет изменять. Итак, мое предлагаемое решение заключается в следующем:

1) Экспортируйте все оригинальные фотографии RAW в дерево каталогов, отсортированное по имени события. 2) Экспортируйте все фотографии в формате JPEG с данными GPS, встроенными в данные EXIF (как iPhoto может сделать). 3) Используйте "exiftool", чтобы извлечь данные GPS из JPEG и скопировать их в соответствующий необработанный файл.

Я могу сделать № 3 по одной фотографии за раз с помощью следующей команды:

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

Файлы Photos-Mod содержат данные GPS из iPhoto, а Photos-Orig - нет. Дерево каталогов и имена файлов будут идентичны, за исключением основного имени каталога и расширения файла (в некоторых случаях мой оригинал также является jpeg). Я надеюсь, что есть хороший способ создать сценарий, который может запускать exiftool для измененных файлов iPhoto в родительском каталоге Photos-Mod, и перемещать данные GPS в исходный файл с соответствующим именем файла и каталогом событий на фотографиях. -Ориг родительский каталог.

У меня просто нет навыков написания сценариев. Любая помощь здесь будет горячей.

1 ответ1

0

Проблема состоит из следующих частей:

  1. Найти все фотографии в каталоге Photos-Mod
  2. Найдите каждое соответствующее фото под Photos-Orig
  3. Вызывать exiftools с правильными аргументами

Поиск всех фотографий

Это легко сделать с помощью выражения типа glob, например ~/Photo-Mod/*/* .

Нахождение соответствующей фотографии

Учитывая полный путь, мы можем заменить Photo-Mod на Photo-Orig . Далее мы изменим расширение файла на * чтобы у нас было другое выражение glob. Если этот глобус не соответствует ни одному файлу, мы выводим сообщение об ошибке, но просто продолжаем.

Вызывать exiftools теперь легко.

Решение Bash

Краткий обзор синтаксиса Bash:

  • Foreach-петля:

    for variable in EXPR; do
      COMMANDS;
    done
    
  • Если еще:

    if COND; then
      COMMANDS;
    else
      COMMANDS;
    fi
    
  • Тестирование файлов: [ -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

Это можно запустить непосредственно из командной строки, удалив все новые строки. Вы также можете поместить его в сценарий оболочки и вызвать его оттуда.

(Примечание: протестировано с аналогичными выражениями 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 были протестированы с Perls v16.3 и v14.2 в Linux.)

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .