PowerShellを使用して、設置先スクリプト内にあるjpg画像の撮影日時(Exif)を使用して、フォルダ作成(例. 241219)を行い、そのフォルダに画像(写真)を仕分けていく。
# System.Drawingライブラリを使用するためにアセンブリをロード
Add-Type -AssemblyName System.Drawing
# スクリプトが置かれているフォルダのパスを取得
$folderPath = Split-Path -Parent $MyInvocation.MyCommand.Path
# 出力するCSVファイルのパスを設定
$outputCsv = Join-Path $folderPath "ImageMetadata.csv"
# ファイル名と撮影日時を保存するための配列を準備
$fileData = @()
# 現在のフォルダ内のすべてのJPEGファイルを取得
Get-ChildItem -Path $folderPath -Filter "*.jpg" | ForEach-Object {
# 現在処理中のファイルオブジェクトを取得
$file = $_
try {
# 画像ファイルをBitmapオブジェクトとして読み込み
$image = New-Object Drawing.Bitmap($file.FullName)
# 画像のExif情報の中から、撮影日時(ID 36867)を取得
$propertyItem = $image.PropertyItems | Where-Object { $_.Id -eq 36867 }
# 撮影日時が存在する場合
if ($propertyItem) {
# バイト配列で取得される撮影日時をASCII文字列に変換
$dateTaken = [System.Text.Encoding]::ASCII.GetString($propertyItem.Value).TrimEnd([char]0)
# 日付を"yymmdd"形式に変換(例: "2024:12:08 12:02:35" → "241208")
# yyyy:MM:dd の形式を 2桁の年 (yy)、月 (MM)、日 (dd) の順に変換
$folderName = $dateTaken.Substring(2,2) + $dateTaken.Substring(5,2) + $dateTaken.Substring(8,2)
# 仕分け先フォルダのパスを設定
$destinationFolder = Join-Path $folderPath $folderName
# フォルダが存在しなければ作成
if (-not (Test-Path -Path $destinationFolder)) {
New-Item -ItemType Directory -Path $destinationFolder | Out-Null
}
# メモリ上の画像リソースを解放
$image.Dispose()
# 画像ファイルを仕分け先フォルダに移動
$destinationFile = Join-Path $destinationFolder $file.Name
Move-Item -Path $file.FullName -Destination $destinationFile
# 結果を配列に追加
$fileData += [PSCustomObject]@{
FileName = $file.Name
DateTaken = $dateTaken
FolderName = $folderName
}
} else {
# 撮影日時が存在しない場合
$image.Dispose()
$fileData += [PSCustomObject]@{
FileName = $file.Name
DateTaken = "Exif情報なし"
FolderName = "不明"
}
}
} catch {
# エラー発生時にエラーメッセージを表示
Write-Host "エラー発生: $($_.Exception.Message)"
# 結果を配列に追加
$fileData += [PSCustomObject]@{
FileName = $file.Name
DateTaken = "取得失敗"
FolderName = "エラー"
}
}
}
# 収集したファイル情報をCSV形式で出力
$fileData | Export-Csv -Path $outputCsv -NoTypeInformation -Encoding UTF8
# 処理完了のメッセージを表示
Write-Host "CSVファイルが作成されました: $outputCsv"
Write-Host "画像の仕分けが完了しました。"
仕分けた画像を元に戻したい場合、以下の移動差し戻しスクリプトを実行する。
# スクリプトが実行されたディレクトリを取得
$scriptDirectory = Split-Path -Parent $MyInvocation.MyCommand.Path
# 現在のディレクトリ内のすべてのフォルダを検索(サブフォルダを除く)
$folders = Get-ChildItem -Path $scriptDirectory -Directory
# 各フォルダ内の.jpg画像を取得し、スクリプトディレクトリに移動する
foreach ($folder in $folders) {
# フォルダ内の.jpg画像を取得
$jpgFiles = Get-ChildItem -Path $folder.FullName -Filter *.jpg
foreach ($file in $jpgFiles) {
try {
# 画像ファイルをスクリプトディレクトリに移動
$destinationPath = Join-Path -Path $scriptDirectory -ChildPath $file.Name
# もし同じ名前のファイルが存在すれば、ファイル名に番号を付けて重複を避ける
$counter = 1
while (Test-Path $destinationPath) {
$newFileName = "{0}_{1}{2}" -f [System.IO.Path]::GetFileNameWithoutExtension($file.Name), $counter, $file.Extension
$destinationPath = Join-Path -Path $scriptDirectory -ChildPath $newFileName
$counter++
}
# ファイルを移動
Move-Item -Path $file.FullName -Destination $destinationPath
Write-Host "Moved: $($file.FullName) to $destinationPath"
}
catch {
Write-Host "Error moving file $($file.FullName): $_"
}
}
}
Write-Host "All files have been moved."
コメント