Как я могу поэтапно датировать фотографии?

У меня есть коллекция фотографий, на которых нет информации о дате. У них нет данных Exif, а даты модификации файлов все идентичны. Единственная последовательность есть в имени файла: image-0001.jpg, image-0002.jpg и т.д.

Теперь я хочу присвоить этим файлам (желательно в Exif) дату с разницей в 10 секунд. Меня не так интересует, какими именно будут базовые дата и время, просто все они увеличиваются на 10 секунд. Таким образом, первое изображение получит 0:00:00, второе 0:00:10, третье 0:00:20 и т. д.

Возможно ли это с помощью ExifTool или других приложений Windows? Мы говорим о нескольких тысячах изображений, так что вручную об этом не может быть и речи ;-)

Ответы (4)

Подобный вопрос уже есть на форумах ExifTool. Это можно сделать с помощью двух последовательных команд ExifTool. Во-первых, убедитесь, что все даты совпадают

exiftool -datetimeoriginal='2015:02:22 00:00:00' DIR

И затем увеличивайте время на каждом

exiftool '-datetimeoriginal+<0:0:${filesequence}0' DIR

Эта команда создает файлы резервных копий. Добавить -overwrite_originalдля подавления создания файлов резервных копий. Добавить -rдля рекурсии в подкаталоги. Если эта команда запускается под Windows CMD, замените одинарные кавычки на двойные.

Многие другие ответы здесь включают зацикливание и запуск exiftool один/два раза для каждого файла. Это распространенная ошибка Exiftool #3 . Самым большим ударом по производительности Exiftool является время запуска. При обработке тысяч изображений это значительно увеличит время обработки.

Привет СтарГик. Чем этот ответ отличается от ответа Junkyardsparkle?
@Bart, здесь $filesequenceволшебная переменная exiftool; в Junkyardsparkle $fileэто переменная bash. Это более портативно; другой связывает время с именем файла, а не с порядком, в котором exiftool их читает.
Аккуратный. У меня было ощущение, что exiftool может сделать что-то подобное, но если это есть в документах, то я пропустил это.
Я не могу заставить это работать. Я использую exiftool "-datetimeoriginal+<0:0:$filesequence" image-0010.jpg(в формате DOS), но результат "0 файлов изображений обновлено, 1 файл изображений не изменен"
Можно ли изменить эту команду, если мне нужно 3 секунды между каждой фотографией?
@Peter Ваш тест не работает, потому что $filesequenceначинается с 0. Когда у вас есть только один файл, он всегда устанавливается только на 0, что делает все это бесполезным. Это должно работать, если у вас есть целый каталог файлов.
Также обратите внимание, что в bash 'vs "имеет большое значение - с двойными кавычками $будет поймано и интерпретировано оболочкой (как в ответе Йенса), но в этом ответе это должна быть одинарная кавычка, чтобы ExifTool интерпретировал ее внутри.
ПРИМЕЧАНИЕ. Вы также должны использовать «-fileorder имя_файла» в команде увеличения, иначе файлы могут фактически не читаться в ожидаемом порядке.
@Peter, изменить его на 3-секундные интервалы возможно, но это немного сложнее. Вам придется использовать -datetimeoriginal+<0:0:${filesequence;$_*=3} (требуются фигурные скобки). В этот момент вы начинаете использовать расширенное форматирование и подсовываете туда некоторый код Perl.
Еще одна вещь, которую следует добавить, это то, что если вы запускаете эти команды в каталоге (бесполезно запускать отдельные файлы, как указал @mattdm), это будет намного быстрее, поскольку ExifTool вызывается только один раз для каждой команды. Любому циклу придется вызывать его для каждого файла, и запуск каждый раз будет большим ударом по производительности.
Ах, у меня сложилось впечатление, что $filesequence извлекает номер из имени файла, но на самом деле он смотрит на порядок сортировки каталогов. Кроме того, в командной строке Microsoft Windows мы должны использовать "вместо '. Но теперь работает идеально!

Поскольку в лучших ответах используется синтаксис, отличный от Windows, я опубликую здесь их код, преобразованный для Microsoft Windows.

Решение @StarGeek, очень быстрое и простое:

Сначала установите базовую метку времени для всех изображений:

exiftool -datetimeoriginal="2015:01:01 12:00:00" DIR

( DIRэто имя папки, содержащей все изображения.)

Затем назначьте добавочные временные метки:

exiftool "-datetimeoriginal+<0:0:${filesequence;$_*=3}" DIR

(В данном случае 3это количество секунд, которое вы хотите между каждой фотографией.)

Обратите внимание на использование двойных кавычек, это необходимо в системах Windows.


Решение @junkyardsparkle, которое изначально было единственным, с которым я мог работать:

Это требует создания пакетного файла из-за задействованных команд.

@echo off
setlocal EnableDelayedExpansion
for %%f in (*.jpg) do (
    echo %%f
    rem Get filename
    set n=%%f
    rem Extract number
    set n=!n:~6,4!
    rem Interpret as decimal
    set /a n=1!n!-10000
    rem Convert to seconds
    set /a n = n*10
    rem Assign base timestamp
    exiftool -DateTimeOriginal="2000:1:1 00:00:00" %%f
    rem Assign time increment
    exiftool -DateTimeOriginal+="00:00:!n!" %%f
)

Попробуйте Ирфанвью . Это бесплатное ПО (AFAIR) с очень гибкой системой пакетного переименования.

Кроме этого, я бы попробовал написать сценарий, что-то вроде

for X in $(seq -w 0 20) ; do
  plus=$(expr $X \* 10)
  exiftool -alldates+="0:0:0 0:0:$plus" image_$X.jpg
done

Первая строка создает цикл по числам в именах файлов, которые у вас есть, например. 00..20. Если у вас есть 1000 изображений, команда будет seq -w 0 1000. Опция -wдобавляет ведущие нули к числам.

Вторая строка определяет приращение - в данном случае 10. Пока без единиц.

Строка формата в третьей строке «0:0:0 0:0:$plus» определяет, что $plusозначает переменная, в данном случае секунды. Если бы вам нужны были минуты, вы бы написали 0:0:0 0:$plus:0. Формат "год:месяц:день час:минута:секунда". Итак, здесь у нас есть 10-секундный шаг.

Это пакет, выполненный в «bash» (оболочка Linux), возможно, вам придется адаптировать его для Windows или использовать живую систему Linux для преобразования.

Обратите внимание, что все файлы должны иметь (идентичный) тег Exif (DateTimeOriginal), прежде чем его можно будет использовать, поскольку он увеличивает только существующие теги. Но вы можете просто написать тег одной командой exiftool.

Я протестировал это с 20 примерами файлов, и теги были написаны правильно.

Интересно, что exiftool работает с > 59 в поле секунд; Круто. Кроме этого, и будучи немного короче и чище, это в основном то же самое, что и мой подход, за исключением того, что мой анализирует индекс из имени файла, а ваш генерирует имена файлов из индекса. В практическом применении, думаю, полдюжины одного и шесть другого. :)
Спасибо, и очень верно. Когда я начал разбираться в этом, ответов не было, так что ты был быстрее. :)

Что ж, я не опубликовал свой ответ на bash, потому что вопрос конкретно касался решения для Windows, но, поскольку это сделали два других человека, вот что я придумал:

for file in *.jpg
do
  exiftool -DateTimeOriginal="1111:11:11 00:00:00" $file
  exiftool -DateTimeOriginal+="00:00:${file:6:4}0" $file
done

Избегает путаницы с командой даты. :)

Обратите внимание, что в той части, где указано ${file:6:4}, «6» представляет точку в имени файла, с которой начинается порядковый номер, а «4» представляет длину этой последовательности. Если ваши файлы точно соответствуют «image-0001.jpg, image-0002.jpg», указанным в вопросе, это будет работать как есть; в противном случае отрегулируйте, чтобы соответствовать.

Это намного круче моего решения. Но его еще можно немного оптимизировать :) вызвав первый exiftool только один раз на все файлы сразу и зациклившись только на второй команде. (Верно?)
Да, это было бы эффективнее. : P В любом случае, ваш ответ - гораздо лучший псевдокод для тех, кто на самом деле пытается перенести его в DOS или что-то еще. Кажется, я не могу избежать злых башизмов, чтобы спасти свою жизнь.
"злые башимы" - это тавтология. :p Но спасибо. На самом деле я начал со скрипта Ruby, но потом понял, что это будет излишеством.
Фантастика! Я использовал ваш пример для написания пакетного файла. Поскольку я не могу писать блоки кода в комментариях, я напишу свой собственный ответ.
@Peter Питер, я не уверен, что это действительно заслуживает того, чтобы быть принятым ответом, хотя ... если предположить, что метод, представленный StarGeek, действительно работает (я его не проверял), это действительно лучшее и самое портативное решение.