■ PowerShellでExif情報を書き込むには? #1

PowerShellでExif情報を参照するには? #2 からの続き

本文中の "$" は半角で読み替えること。


スキャンで保存した画像ファイルに"撮影日時"を付加させたい。

調査

画像ファイルに撮影日時を付加させるには、PowerShellでExif情報を参照するには? #1 でExif情報表示プログラムを作成したが、Imageオブジェクトの PropertyItemsプロパティに 撮影日時(ID:9003 と ID:9004) の情報を付加させれば良さそうである。
その為には、まず PropertyItemオブジェクト を構築、撮影日時情報をセットし、それをPropertyItemsに追加すれば良い、と思ったが、残念ながらダメだった。
PropertyItemオブジェクト の説明によると、このクラスはパブリックコンストラクターが無いのでオブジェクトの構築ができないのである。

上記説明によると、Imageオブジェクトのプロパティ GetPropertyItemメソッド で存在するPropertyItemを取得、値を設定し、SetPropertyItemメソッド で値を書き戻す、ということらしい。

とりあえずは、何でも良いのでPropertyItemオブジェクトを取得すれば良い?
$item = $image.PropertyItems | Select-Object -First 1
PropertyItemが取得できたので値を設定。
Idは 9000、9003、9004

Id:9000

Id:9000はExifのバージョン。
以下の値を設定する。
Id: 9000
Len: 4
Type: 7
Value: 48 50 49 48

Id:9003、9004

Id:9003は原画像データの生成日時、Id:9004はデジタルデータの作成日時、
双方に同じ値をセットしておけば良いと思う。
Id: 9003 および 9004
Len: 20
Type: 2
Value: "YYYY:MM:DD HH:MM:SS" をASCIIコード化した数値、配列20番目は"0"
今回は "2020:08:19 13:04:00" を設定することとする。
ASCIIコードへの変換は #18:文字列をASCIIコードに変換する を参照。
ASCIIコード変換+最後に0を付加した値は以下の通り。
50 48 50 48 58 48 56 58 49 57 32 49 51 58 48 52 58 48 48 0

これらをまとめると以下のようになる。
# Id:9000 Exifバージョン
$item.Id = 0x9000
$item.Len = 4
$item.Type = 7
$item.Valye = @(48,50,49,48)
$image.SetPropertyItem($item)

# Id:9003 原画像データの生成日時
$item.Id = 0x9003
$item.Len = 20
$item.Type = 2
$item.Value = @(50,48,50,48,58,48,56,58,49,57,32,49,51,58,48,52,58,48,48,0)
$image.SetPropertyItem($item)

# Id:9004 デジタルデータの作成日時
$item.Id = 0x9004
$item.Len = 20
$item.Type = 2
$item.Value = @(50,48,50,48,58,48,56,58,49,57,32,49,51,58,48,52,58,48,48,0)
$image.SetPropertyItem($item)

ファイルへの保存

ファイルの保存は ImageオブジェクトのSaveメソッドで、引数に保存ファイル名を指定すれば良い。
ただ、オリジナルのファイルは万が一のために残しておきたいので、別フォルダに同じファイル名で保存する。
フルパスからファイル名のみを取得するには "(Split-Path -Path $inputFile -Leaf)" で取得できる。
※参考:PowerShell学習 #19:パス文字列の操作
引数 $outputPath で出力先パスを取得し、オリジナルファイル名で保存する場合以下のようになる。
$outputFile = Join-Path $outputPath (Split-Path $inputFile -Leaf)
$image.Save($outputFile)

サンプルソース

書き込む撮影はプログラム固定となっている。
Param (
  [Parameter(mandatory=$true)][String]$inputFile,
  [Parameter(mandatory=$true)][String]$outputPath
)
Add-Type -AssemblyName "System.Drawing"

$image = New-Object System.Drawing.Bitmap($inputFile)

$item = $image.PropertyItems | Select-Object -First 1

# Id:9000 Exifバージョン
$item.Id = 0x9000
$item.Len = 4
$item.Type = 7
$item.Value = @(48,50,49,48)
$image.SetPropertyItem($item)

# Id:9003 原画像データの生成日時
$item.Id = 0x9003
$item.Len = 20
$item.Type = 2
$item.Value = @(50,48,50,48,58,48,56,58,49,57,32,49,51,58,48,52,58,48,48,0)
$image.SetPropertyItem($item)

# Id:9004 デジタルデータの作成日時
$item.Id = 0x9004
$item.Len = 20
$item.Type = 2
$item.Value = @(50,48,50,48,58,48,56,58,49,57,32,49,51,58,48,52,58,48,48,0)
$image.SetPropertyItem($item)

# 書き込み
$outputFile = Join-Path $outputPath (Split-Path $inputFile -Leaf)
$image.Save($outputFile)

$image.Dispose()

正常に書き込めた事を、エクスプローラーのプロパティで確認した。

- 以上 -




自作プログラム, PowerShell, Exif

0 件のコメント:

その他の記事