![ПереименоватьFromExif.ps1](https://rvso.com/image/1465785/%D0%9F%D0%B5%D1%80%D0%B5%D0%B8%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2%D0%B0%D1%82%D1%8CFromExif.ps1.png)
У меня есть папка с фотографиями, сделанными разными камерами, и все эти фотографии имеют правильнуюДатаВремяОригиналУстановлен тег EXIF.
Предположим, что список файлов выглядит следующим образом:
20150831_153712.jpg
IMG_5246.JPG
IMG_5247.JPG
20150902_201425.jpg
Теперь я хотел бы узнать, как переименовать эти файлы таким образом, основываясь наДатаВремяОригиналтег конечно:
001_IMG_5246.JPG
002_20150831_153712.jpg
003_IMG_5247.JPG
004_20150902_201425.jpg
В основном я хочуexiftool(или пакетная программа Windows, если это невозможно напрямую)Сортироватьвся папка JPEG-файловДатаВремяОригиналвозрастание и операция переименования должна поставитьприлавокпрефикс перед именем файла (таким образом сохраняя исходное имя файла).
Я бы также хотел узнать, как сделатьтестовая команда для предварительного просмотра переименованияпрежде чем это произойдет (чтобы увидеть, если что-то не так, я полагаю, используяИмяТестаярлык).
решение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
.
решение2
Я проверил пару инструментов переименования. Основная проблема в том, что такие инструменты какПереименовать МастериExifToolможет получить доступ к данным EXIF. Но я не смог найти способ создать нумерованный список.
Поэтому я написал скрипт PowerShell, чтобы сделать это. Я прокомментировал каждую строку. Это должно быть легко понять. Просто прочитайте их.
Первое, что мне пришлось сделать, это поискатьИдентификатор "DateTimeOriginal"поэтому мы можем использовать GetPropertyItem(MyExifID)
. Во-вторых, мы добавляем все изображения из заданной папки, которые на самом деле имеют DateTimeOriginal, в массив. Отсюда все было просто. Мы сортируем массив по столбцу даты, увеличиваем простой счетчик и создаем наше новое имя файла с помощью шаблона 000_oldname
.
Этот скрипт ничего не изменит.Он выводит только что-то вроде:
Используйте его, чтобы проверить, что будет делать скрипт. После того, как вы проверили возможные результаты, удалите индикатор комментария #
перед строкой #Rename-Item $_[0].Fullname $newName
.С этого момента скрипт будет переименовывать ваши файлы соответствующим образом.
ПереименоватьFromExif.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
Использованные ресурсы
- http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html
- http://blogs.technet.com/b/jamesone/archive/2007/07/13/exploring-photographic-exif-data-using-powershell-of-course.aspx
- http://blog.cincura.net/233463-переименование-файлов-на-основе-exif-данных-в-powershell/
- http://www.happysysadm.com/2011/01/многомерные-массивы-в-powershell.html
- http://www.orcsweb.com/blog/james/fun-with-powershell-sorting-multidimensional-arrays-and-arraylists/
- http://blogs.technet.com/b/heyscriptingguy/archive/2008/06/02/hey-scripting-guy-how-can-i-use-leading-zeroes-when-displaying-a-value-in-windows-powershell.aspx