我有一个文件夹,里面有用不同相机拍摄的照片,所有这些照片都有正确的日期时间原始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
基本上我想要外置工具(如果无法直接使用,则使用 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
我检查了几个重命名工具。主要问题是,像重命名主文件和Exif工具可以访问 EXIF 数据。但我找不到生成编号列表的方法。
所以我写了一个 PowerShell 脚本来做这件事。我给每一行都加了注释。应该很容易理解。只要读一下就行了。
我要做的第一件事就是搜索“DateTimeOriginal”的 ID所以我们可以使用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-renaming-files-based-on-exif-data-in-powershell/
- http://www.happysysadm.com/2011/01/multiDimension-arrays-in-powershell.html
- http://www.orcsweb.com/blog/james/fun-with-powershell-sorting-multiDimension-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