1

У меня есть папка с фотографиями, сделанными с разных камер, и все эти изображения имеют правильный набор тегов 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 ).

2 ответа2

1

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

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

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

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

Используйте его, чтобы проверить, что будет делать скрипт. После проверки возможных результатов удалите индикатор комментария # перед строкой #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 @{Expression={$_[1]} } | 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]{3}_") {
        #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

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

1

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

Попробуйте эту команду:
ExifTool "-TestName<${FileSequence;$_=0 x(3-length($_+1)).($_+1)}_$filename" -FileOrder DateTimeOriginal DIR

Если это работает, просто замените -TestName на -FileName:
ExifTool "-FileName<${FileSequence;$_=0 x(3-length($_+1)).($_+1)}_$filename" -FileOrder DateTimeOriginal DIR

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

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