重命名FromExif.ps1

重命名FromExif.ps1

我有一个文件夹,里面有用不同相机拍摄的照片,所有这些照片都有正确的日期时间原始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 一起使用的项目是选项-FileOrderFileSequence标签,再加上使用高级格式化选项的一点 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

使用的资源

相关内容