さまざまなカメラで撮影した写真を含むフォルダーがあり、これらすべての写真には正しいDateTimeOriginalEXIFタグが設定されています。
次のようなファイルのリストがあるとします。
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バッチプログラム)をsort JPEGのフォルダー全体にDateTimeOriginal昇順で、名前変更操作では、ファイル名の前にcounterプレフィックスを付ける必要があります(したがって、元のファイル名を保持します)。
また、発生する前に名前の変更をプレビューするためのテストコマンドを実行する方法も知りたいです(何かが間違っているかどうかを確認するには、TestNameタグ)。
ExifToolで使用したい項目は、_-FileOrder
_オプションとFileSequence
タグに加えて、高度なフォーマットオプションを使用したPerlです。 FileOrderオプションは、オプションでリストした時間に基づいてファイルを並べ替えます。これにより、各ファイルを2回読み取る必要があるため、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-length
_の3を必要な数に変更します。開始番号を変更するには、_$_+1
_の1を変更します。
名前変更ツールをいくつか確認しました。主な問題は、 マスターの名前変更 や ExifTool などのツールがEXIFデータにアクセスできることです。しかし、番号付きリストを生成する方法が見つかりませんでした。
そこで、PowerShellスクリプトを作成してそれを実行しました。各行にコメントしました。わかりやすいはずです。それらを読んでください。
私が最初にやらなければならなかったのは、 "DateTimeOriginal"のID を検索して、GetPropertyItem(MyExifID)
を使用できるようにすることでした。次に、実際にDateTimeOriginalを持つ特定のフォルダーのすべての画像を配列に追加します。ここからは簡単でした。配列を日付列で並べ替え、単純なカウンターをインクリメントし、パターン000_oldname
で新しいファイル名を作成します。
このスクリプトは何も変更しません。次のようなものだけを出力します。
これを使用して、スクリプトが何をするかを確認します。考えられる結果を確認したら、行#
の前にあるコメントインジケーター#Rename-Item $_[0].Fullname $newName
を削除します。 今後、スクリプトはそれに応じてファイルの名前を変更します。
# 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