Open1
PowerShellで System.Drawing.Bitmap.Save するとEXIF情報がエクスプローラーから見えなくなる

ファイルの更新日をEXIFの撮影日時としたくてChatGPTに聞きながらPowerShellのコードを書いた。
撮影日時の書き込みはできるようになったんだけど、書き込みを行うと、もともとあったユーザーコメントなどの情報がエクスプローラーから表示できなくなってしまう。
コードをコメントアウトしながら何が原因か調べていたらどうもSaveメソッドを使うとEXIFが消えるっぽい?というわけで、元あったユーザーコメントを明示的に書き込むようにしてみたが状況は改善せず。
EXIFを読むプログラムをPowerShellで書いて調べたところ、Saveメソッドで作った画像ファイル、エクスプローラーからはEXIF読めないけど、EXIFデータは存在するっぽい。
もうどうしたらいいのかわからないのでお手上げ。
write_exif.ps1
Add-Type -AssemblyName System.Drawing
$baseFolder = "C:\test"
# 撮影日時のタグ
$DateTimeOriginalIndex = 0x9003
$DateTimeDegitizedIndex = 0x9004
$UserCommentIndex = 0x9286
$jpegFiles = Get-ChildItem -Path $baseFolder -Filter "*.jpg" -File
foreach ($file in $jpegFiles) {
$image = New-Object System.Drawing.Bitmap($file.FullName)
$propertyItems = $image.PropertyItems
# ファイル更新日を取得 (作成日はコピペで更新されるので更新日がよさそう)
$creationDate = $file.LastWriteTime
# 撮影日時を取得。EXIFデータが存在するならSkip
Try {
$exifDateTakenProperty = $image.GetPropertyItem($DateTimeOriginalIndex)
$image.Dispose()
Write-Output("Skip: " + $file.Name)
continue
}
Catch {
$item = $image.PropertyItems | Select-Object -Last 1
# Id:9003 原画像データの生成日時
$item.Id = $DateTimeOriginalIndex
$item.Len = 20
$item.Type = 2
$item.Value = [System.Text.Encoding]::ASCII.GetBytes($creationDate.ToString("yyyy:MM:dd HH:mm:ss`0"))
$image.SetPropertyItem($item)
# Id:9004 Digitalデータの生成日時
$item.Id = $DateTimeDegitizedIndex
$image.SetPropertyItem($item)
$item.Id = 0x0132
$image.SetPropertyItem($item)
$item.Id = 0x0131
$item.Value = [System.Text.Encoding]::ASCII.GetBytes("Stable Diffusion")
$image.SetPropertyItem($item)
}
#$exifDateTakenProperty.Value = [System.Text.Encoding]::ASCII.GetBytes($creationDate.ToString("yyyy:MM:dd HH:mm:ss`0"))
#$image.SetPropertyItem($exifDateTakenProperty)
# なぜかコメントが消えてしまうので、プロパティアイテムの中からJPEGコメントを検索
$comment = $propertyItems | Where-Object { $_.Id -eq $UserCommentIndex }
Write-Output([System.Text.Encoding]::Unicode.GetString($comment.Value))
$image.SetPropertyItem($comment)
# 更新した画像を保存
$bufKey = "_m_write_exif_m_"
$newFilePath = $baseFolder + "\" + $bufKey + $file.Name
$image.Save($newFilePath, [System.Drawing.Imaging.ImageFormat]::Jpeg)
$image.Dispose()
Move-Item $newFilePath $file.FullName -Force
Write-Output("Move: " + $file.Name)
}