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へ置いておいた。

いいなと思ったら応援しよう!