Переименуйте JPEG, добавив префикс в соответствии с датой

2285
virtualdj

У меня есть папка с фотографиями, сделанными с разных камер, и все эти изображения имеют правильный набор тегов DateTimeOriginal EXIF.

Предположим, список файлов выглядит так:

20150831_153712.jpg IMG_5246.JPG IMG_5247.JPG 20150902_201425.jpg 

Теперь я хотел бы знать, как переименовать эти файлы таким образом, основываясь на теге DateTimeOriginal, конечно:

001_IMG_5246.JPG 002_20150831_153712.jpg 003_IMG_5247.JPG 004_20150902_201425.jpg 

По сути, я хочу, чтобы exiftool (или пакетная программа Windows, если это невозможно напрямую) сортирует целую папку JPEG по возрастанию DateTimeOriginal, а операция переименования должна ставить префикс счетчика перед именем файла (таким образом, сохраняя исходное имя файла).

Я также хотел бы, как сделать тестовую команду для предварительного просмотра переименования, прежде чем оно произойдет (чтобы увидеть, если что-то не так, я полагаю, с помощью тега TestName ).

1

2 ответа на вопрос

1
nixda

Я проверил пару инструментов переименования. Основная проблема заключается в том, что такие инструменты, как Rename Master и ExifTool, могут получить доступ к данным EXIF. Но я не смог найти способ создать нумерованный список.

Поэтому я написал сценарий PowerShell для этого. Я прокомментировал каждую строку. Это должно быть легко понять. Просто прочитайте их.

Первое, что мне нужно было сделать, это поиск по идентификатору «DateTimeOriginal», чтобы мы могли его использовать GetPropertyItem(MyExifID). Во-вторых, мы добавляем в массив все изображения из заданной папки, которые на самом деле имеют DateTimeOriginal. Отсюда было легко. Мы сортируем столбец массив по дате, увеличиваем простой счетчик и строим наше новое имя файла с помощью шаблона 000_oldname.

Этот скрипт ничего не изменит. Это только выводит что-то вроде:

enter image description here

Используйте его, чтобы проверить, что будет делать скрипт. После проверки возможных результатов удалите индикатор комментария #перед строкой #Rename-Item $_[0].Fullname $newName. С этого момента скрипт будет соответственно переименовывать ваши файлы.

RenameFromExif.ps1

# Set image folder to process $strDirectory = "T:\Pictures"  # Create empty array $arrSortMe = @()  # Load Windows library to access EXIF data [void][Reflection.Assembly]::LoadWithPartialName("System.Drawing")  # Loop through all JPGs and JPEGs in the given image folder Get-ChildItem -Path "$strDirectory\*" -Include *.jpg,*.jpeg | ForEach {  # Load current image into Powershell as bitmap object $img = New-Object -TypeName system.drawing.bitmap -ArgumentList $_.FullName  # Error handling for images which doesn't have the specified EXIF data Try {  # Get EXIF data with ID 36867 - which is "DateTimeOriginal" $intExif = [Byte[]]$img.GetPropertyItem(36867).Value  # Release image or else later we can't rename it $img.Dispose()  # Convert EXIF data from byte array to string $strExif = [System.Text.Encoding]::Default.GetString($intExif, 0, $intExif.Length-1)  # Convert EXIF data from string to datetime $dateExif = [DateTime]::ParseExact($strExif, 'yyyy:MM:dd HH:mm:ss', $null)  # Add to multidimensional array: [0]=current_file and [1]=datetime $arrSortMe += ,@($_, $dateExif) } Catch {} }  Write-host "DateTimeTaken" `t`t`t "New Name" `t`t`t "Old Fullname" # Sort array by datetime and pipe the sorted array to a foreach loop $arrSortMe | Sort-Object @ } | ForEach {$i=0}{  # Increment a simple counter starting with 0, so the first image gets the "1" $i++  # Format the counter to 3-digits, append an underscore followed by the old image name $newName = $i.ToString("000") + "_" + $_[0].Name   # Don't rename images which already have three digits as filename start If ($_.Name -notmatch "^[\d]_") { #Rename-Item $_[0].Fullname $newName }  # Only for debugging  Write-host $_[1].Date `t $newName `t $_[0].Fullname }  # Clear all variables. System variables are readonly so we don't mind using * to get all Remove-Variable * -ErrorAction SilentlyContinue 

Использованные ресурсы

Интересный сценарий, спасибо! Работает отлично. Но решение @StarGeek кажется проще, потому что оно опирается только на ** ExifTool **. Ваш закомментированный пример хорош для изучения Powershell. virtualdj 8 лет назад 0
1
StarGeek

Элементы, которые вы хотите использовать с ExifTool - это -FileOrderпараметры и FileSequenceтег, а также немного Perl с использованием опции расширенного форматирования. Параметр FileOrder будет сортировать файлы по времени, указанному в списке с помощью параметра. Это немного замедляет ExifTool, потому что он должен читать каждый файл дважды, но все же обычно быстрее, чем другие опции, такие как циклы и вызов ExifTool для каждого цикла. Тег FileSequence является внутренним для ExifTool и отслеживает номер обрабатываемого в данный момент файла. Он начинается с 0, поэтому нам нужно добавить 1 к нему в расширенной обработке. Это также, где мы добавим нули, так что это будет как минимум 3 символа.

Попробуйте эту команду:
ExifTool "-TestName<$_$filename" -FileOrder DateTimeOriginal DIR

Если это работает, просто замените -TestNameна -FileName:
ExifTool "-FileName<$_$filename" -FileOrder DateTimeOriginal DIR

Чтобы изменить количество дополняемых нулей, измените 3 3-lengthна желаемое число. Чтобы изменить начальный номер, измените 1 в $_+1.

Это почти идеально, спасибо! Но есть две причуды с ** 10 ** и ** 100 **, у которых слишком много ведущих 0: `'20150831_124835.jpg' -> '009_20150831_124835.jpg', '20150831_131539.jpg' -> '0010_20150831_131539 .jpg ',' IMG_5291.JPG '->' 099_IMG_5291.JPG ',' IMG_5292.JPG '->' 0100_IMG_5292.JPG ',' 20150901_170708.jpg '->' 101_20150901_170708.jpg'`. virtualdj 8 лет назад 0
Также стоит отметить, что тег ** TestName ** был введен начиная с ** версии 9.64 ** ExifTool (я использовал более старую версию, и она потерпела неудачу с большим количеством предупреждений: ни один из доступных для записи тегов не установлен из ****) Сообщения). Это может быть полезно для других пользователей, читающих этот ответ. virtualdj 8 лет назад 0
О да. Это потому, что я измерил длину числа, а затем добавил 1 к числу. Моя глупая ошибка - попытаться сделать расширенное форматирование максимально коротким. Исправил команду. Если вам нужно начать с другого номера, вам нужно исправить оба вхождения `($ _ + 1)`. StarGeek 8 лет назад 0

Похожие вопросы