画像管理はWindows10の「フォト」アプリを利用しています。
フォトアプリの画像管理のベースは撮影日時らしく、インポート機能を利用すると、撮影日ごとにフォルダが作られ、画像が振り分けられます。
インポート機能では、リムーバブルメディア以外のインポートは、フォルダへの参照が作られるだけの様で、管理フォルダ配下に集約したい自分の思っていた挙動ではなく...既にPC内に存在する画像もフォトアプリの管理ができるよう、Powershellで撮影日ベースの仕分けスクリプトを書いてみました。
方針
- 元画像フルパス(a)、コピー先の親フォルダパス(b)をインプットにする
- (a)からExif情報を基に撮影日時を取得する。Exifの撮影日時について☟
- 撮影日時を基に、「yyyy-mm-dd」形式のフォルダ名(c)を作成する
- (b)に、(c)フォルダが存在するかチェックし、存在しなければ作成
- (a)を、(b)の(c)フォルダにコピーする
コード
フォルダ作成要否チェック用のパラメータをつけてみた
param( [string]$filename # 処理対象ファイル名(フルパス) ,[string]$targetDir # 移動先親ディレクトリパス ,[switch]$test # このパラメータがついていたら、ディレクトリ作成、コピーはしない ) # エラーがあった時点で処理終了 $ErrorActionPreference = "stop" [void][System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") # 撮影日取得処理 # 引数1 :Bitmapオブジェクト # 戻り値:なし function GetSatsueiDate($sourceImage){ $propDate="" # Exif情報を取得 $private:properties = $sourceImage.PropertyItems foreach($property in $properties){ if($property.Id -eq 36867){ #0x9003 PropertyTagExifDTOrig $propDate = [System.Text.Encoding]::ASCII.GetString($property.Value) break } } return $propDate } function script:makeFolderName($originalSatsueiDate){ $folderName = "" if($originalSatsueiDate -eq $null -or $originalSatsueiDate.length -lt 1){ return $folderName } # yyyy.mm.ddを抽出しyyyy-mm-ddに変換 if($originalSatsueiDate -match "(?<SatsueiDate>\d\d\d\d.\d\d.\d\d?)"){ $folderName = $Matches["SatsueiDate"].replace(":","-") return $folderName }else{ return $folderName } } # メイン処理 # 引数1 :元画像ファイルのフルパス # 戻り値:なし function script:Main($originalFileName){ $private:sourceImage = $null try{ # 元画像取得(Bitmap) $sourceImage = New-Object System.Drawing.Bitmap($originalFileName) # 撮影日取得 $satsueiDate = GetSatsueiDate $sourceImage # 元Bitmapを閉じる $sourceImage.Dispose() # 撮影日付をyyyy-mm-dd形式に変換し、フォルダ名を作成 $folderName = makeFolderName $satsueiDate $joinedPath = Join-Path $targetDir $folderName if (Test-Path $joinedPath){ echo "存在します:$joinedPath" }else{ echo "作成します(テスト):$joinedPath" if($test -eq $false){ echo "作成します:$joinedPath" mkdir $joinedPath >$null 2>&1 } } if($test -eq $false){ cp $originalFileName $joinedPath } }catch{ echo "例外が発生しました:$error" }finally{ try{ if($null -ne $sourceImage){ $sourceImage.Dispose() } }catch{ echo "画像クローズ時の例外:$error" } } } # 撮影日取得処理の実行 Main $filename
実行結果
# 実際にフォルダ作成、コピーを実行する場合 PS D:\Documents\scripts> .\撮影日で写真を仕分け.ps1 -filename "C:\Users\hoge\Pictures\2015\2015-01-02\IMG_20150102_180534.jpg" -targetDir D:\ 作成します:D:\2015-01-02 # 実際にフォルダ作成、コピーを実行しない場合 PS D:\Documents\scripts> .\撮影日で写真を仕分け.ps1 -filename "C:\Users\hoge\Pictures\2015\2015-01-02\IMG_20150102_180534.jpg" -targetDir D:\ -test 作成します(テスト):D:\2015-01-02