本文中の "$" は半角で読み替えること。
スキャンで保存した画像ファイルに"撮影日時"を付加させたい。
調査
画像ファイルに撮影日時を付加させるには、PowerShellでExif情報を参照するには? #1 でExif情報表示プログラムを作成したが、Imageオブジェクトの PropertyItemsプロパティに 撮影日時(ID:9003 と ID:9004) の情報を付加させれば良さそうである。
その為には、まず PropertyItemオブジェクト を構築、撮影日時情報をセットし、それをPropertyItemsに追加すれば良い、と思ったが、残念ながらダメだった。
PropertyItemオブジェクト の説明によると、このクラスはパブリックコンストラクターが無いのでオブジェクトの構築ができないのである。
上記説明によると、Imageオブジェクトのプロパティ GetPropertyItemメソッド で存在するPropertyItemを取得、値を設定し、SetPropertyItemメソッド で値を書き戻す、ということらしい。
とりあえずは、何でも良いのでPropertyItemオブジェクトを取得すれば良い?
Idは 9000、9003、9004
その為には、まず PropertyItemオブジェクト を構築、撮影日時情報をセットし、それをPropertyItemsに追加すれば良い、と思ったが、残念ながらダメだった。
PropertyItemオブジェクト の説明によると、このクラスはパブリックコンストラクターが無いのでオブジェクトの構築ができないのである。
上記説明によると、Imageオブジェクトのプロパティ GetPropertyItemメソッド で存在するPropertyItemを取得、値を設定し、SetPropertyItemメソッド で値を書き戻す、ということらしい。
とりあえずは、何でも良いのでPropertyItemオブジェクトを取得すれば良い?
$item = $image.PropertyItems | Select-Object -First 1PropertyItemが取得できたので値を設定。
Idは 9000、9003、9004
Id:9000
Id:9000はExifのバージョン。
以下の値を設定する。
以下の値を設定する。
Id: 9000
Len: 4
Type: 7
Value: 48 50 49 48
Len: 4
Type: 7
Value: 48 50 49 48
Id:9003、9004
Id:9003は原画像データの生成日時、Id:9004はデジタルデータの作成日時、
双方に同じ値をセットしておけば良いと思う。
ASCIIコードへの変換は #18:文字列をASCIIコードに変換する を参照。
ASCIIコード変換+最後に0を付加した値は以下の通り。
双方に同じ値をセットしておけば良いと思う。
Id: 9003 および 9004
Len: 20
Type: 2
Value: "YYYY:MM:DD HH:MM:SS" をASCIIコード化した数値、配列20番目は"0"
今回は "2020:08:19 13:04:00" を設定することとする。Len: 20
Type: 2
Value: "YYYY:MM:DD HH:MM:SS" をASCIIコード化した数値、配列20番目は"0"
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 で出力先パスを取得し、オリジナルファイル名で保存する場合以下のようになる。
ただ、オリジナルのファイルは万が一のために残しておきたいので、別フォルダに同じファイル名で保存する。
フルパスからファイル名のみを取得するには "(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 件のコメント:
コメントを投稿