Exifの撮影日時を変更
前回の記事で写真の更新日時を変更したものの、Google Photoへアップしてみたら、ご丁寧にExifの撮影日時を見ていたのでズコーとなり、改めてExifの撮影日時を変更するプログラムを作成。ちなみにExifは「えぐじふ」と読むらしい。
フォルダ以下全部~という処理は、前回の記事を参考にしてそのうちやるとして、ひとまずピンポイントで1ファイルだけ修正する処理を作った。もともとの要望(フォルダ以下全部)を実現するためには、組み合わせればできる話。
# 写真のExif情報(撮影日)を編集する
# 2020/3/8 yo16
$photoPath = 'DSC00672.JPG';
$p_addHour = 24;
$curDirPath = Convert-Path .;
$photoPath = $curDirPath + '\' + $photoPath;
#echo $photoPath
Add-Type -AssemblyName System.Drawing
$img = New-Object Drawing.Bitmap($photoPath);
#for($i=0; $i -lt $img.PropertyItems.Length; $i++ ){
#$prop = $img.PropertyItems[$i];
foreach($prop in $img.PropertyItems){
if($prop.Id -eq 36867){ # 撮影日時
# 文字列がバイトで入ってるので変換
$byteArray = $prop.Value;
#echo $byteArray;
$strDt = [System.Text.Encoding]::ASCII.GetString($prop.Value);
$strDt = $strDt.Substring(0,19)
Write-Host( "["+$strDt+"]");
# 日付型へ変換
$dtOld = [DateTime]::ParseExact($strDt, "yyyy:MM:dd HH:mm:ss", $null);
#Write-host($dtOld);
# 時間を足し算
$dtNew = $dtOld.AddHours($p_addHour);
Write-host($dtNew);
# 文字列に変換
$strDtNew = $dtNew.ToString("yyyy:MM:dd HH:mm:ss");
Write-host($strDtNew);
# バイト列に変換
$byteDtNew = [system.text.encoding]::ASCII.GetBytes($strDtNew)
# プロパティを変更
$prop.Value = $byteDtNew;
$img.SetPropertyItem($prop);
}
}
# 保存
$tmpPath = $photoPath + ".tmp.jpg"
$img.Save($tmpPath, [System.Drawing.Imaging.ImageFormat]::Jpeg);
$img.Dispose();
$img = $null;
# オリジナルとテンポラリファイルを入れ替え
del $photoPath
ren $tmpPath $photoPath
ポイントは、バイナリで入ってる文字をテキストにしてDateTimeにしてからいじる。そしてまた戻す。それを、新しい画像ファイルに設定して保存。古いファイルと差し替えて完了。
当然のことながら、ファイルの作成日時と更新日時は今の時間になるので、前回の記事と同じようにしたければ、この後に作成日時・更新日時をいじる処理を加えることになる。
こちらもソースはgithubへ置いておいた。