2017-07-17 38 views
0

イメージファイルのEXIFプロパティからGPSロケーションデータを抽出します。私はSystem.Drawing.Bitmapクラスを使って値を生データにしています。私は探している値を抽出することができますが、それらはバイトとして返されるか、バイトの配列になる可能性があり、バイトを賢明な数値に変換するのに役立つ必要があります。ここで私はこれまで持っているものである:私は私が探していますプロパティタグがあることを知っているEXIF GPS Tag ReferenceからPowerShellを使用してバイト配列からGPS数値を抽出する

$imagePath = 'C:\temp\picTest\WP_20150918_003.jpg' 
$imageProperties = New-Object -TypeName System.Drawing.Bitmap -ArgumentList $imagePath 

  • は0x0001 - GPSLatitudeRef - 緯度が北か南かどうかを示します緯度。
  • 0x0002 - GPSLatitude - 緯度を示します。
  • 0x0003 - GPSLongitudeRef - 経度が東経か西経かを示します。
  • 0x0004 - GPSLongitude - 経度を示します。
  • 0x0005 - GPSAltitudeRef - 基準高度として使用される標高を示します。
  • 0x0006 - GPSAltitude - GPSAltitudeRefの参照に基づく標高を示します。

まず私はGPSLatitudeRefを得る:

$imageProperies.PropertyItems | ? ID -eq 0x0001 

と私が手:

Id Len Type Value 
-- --- ---- ----- 
1 2 2 {78, 0} 

System.Drawing libraryのためのMSDNドキュメントによると、 "2" のPropertyItem.TypeはASCIIです。

私は変数に値をロードします:変数リターンに

$GPSLatRef = $imageProperties.PropertyItems| Where ID -eq 0x0001 
$GPSLatRef = $GPSLatRef.Value 
$GPSLatRef 
78 
0 

をGet-MemberをSystem.Byteを入力します。私はASCIIに戻すのバイトを変換する方法を知っている:

$GPSLatRef = [System.Text.Encoding]::ASCII.GetString($GPSLatRef.Value) 
$GPSLatRef 

リターン:

N 

しかし、物事は緯度(数値)GPSLatitude値(0×0002)と私のためにトリッキー取得:

$imageProperies.PropertyItems | ? ID -eq 0x0002 

リターン:

Id Len Type Value 
-- --- ---- ----- 
2 24 5 {37, 0, 0, 0...} 

負荷変数の値に戻る:上記参照MSDNのドキュメントによれば

37 
0 
0 
0 
1 
0 
0 
0 
40 
0 
0 
0 
1 
0 
0 
0 
220 
182 
0 
0 
232 
3 
0 
0 

、 "5" のPropertyItem.Type 「がその値を指定:

$GPSLatitiude = $imageProperties.PropertyItems| Where ID -eq 0x0002 
$GPSLatitiude.Value 

が返される値でありますデータメンバは配列の対の符号なしlong整数です。 各対は小数部を表す;第1の整数は分子であり、第2の整数は分母である。

Windowsエクスプローラでファイル自体のプロパティを見ると、10進形式のGPSロケーション値が表示されます。

"37;40;46.812000000005156" 
上記値データ、およびドキュメントからのデータ型の説明から

、と私は$ GPSLatitude.Valueが実際に私に二つの整数の三つの異なるセットを示していることを推測することができますWindowsのエクスプローラからの小数の値との比較各個に。例えば、

37 
0 
0 
0 

= 37

1 
0 
0 
0 
= 1

と私は正しい軌道に乗っています知っているように、Windowsエクスプローラから小数点値と一致した= 37 1分の37、。

どのようにGPSLatitudeプロパティにある(配列の?)バイトから3つの値のセットを分割できますか?バイト内のデータは長い整数として記述されていますが、Windowsエクスプローラに表示される10進数値は、結果が小数点の右側の15桁の数字になる可能性があることを示しています。プロパティ値からのバイト内の2つの長い整数は、[double]またはおそらく[decimal]に格納する必要がありますか?

答えて

0

このスニペットはあなたを緯度与えると経度の詳細ます、私はバイト配列からデータを抽出するためのBitConverterを使用しています。そのため

[double]$LatDegrees = (([System.BitConverter]::ToInt32($imageProperties.GetPropertyItem(2).Value, 0))/([System.BitConverter]::ToInt32($imageProperties.GetPropertyItem(2).Value, 4))); 
[double]$LatMinutes = ([System.BitConverter]::ToInt32($imageProperties.GetPropertyItem(2).Value, 8))/([System.BitConverter]::ToInt32($imageProperties.GetPropertyItem(2).Value, 12)); 
[double]$LatSeconds = ([System.BitConverter]::ToInt32($imageProperties.GetPropertyItem(2).Value, 16))/([System.BitConverter]::ToInt32($imageProperties.GetPropertyItem(2).Value, 20)); 
[double]$LonDegrees = (([System.BitConverter]::ToInt32($imageProperties.GetPropertyItem(4).Value, 0))/([System.BitConverter]::ToInt32($imageProperties.GetPropertyItem(4).Value, 4))); 
[double]$LonMinutes = ([System.BitConverter]::ToInt32($imageProperties.GetPropertyItem(4).Value, 8))/([System.BitConverter]::ToInt32($imageProperties.GetPropertyItem(4).Value, 12)); 
[double]$LonSeconds = ([System.BitConverter]::ToInt32($imageProperties.GetPropertyItem(4).Value, 16))/([System.BitConverter]::ToInt32($imageProperties.GetPropertyItem(4).Value, 20)); 
"Latitude: $LatDegrees;$LatMinutes;$LatSeconds" 
"Longitude: $LonDegrees;$LonMinutes;$LonSeconds" 
+0

おかげで - 私は私が私が理解しておいてください聞かせて、それが理にかなっていると信じて: – osboy1

+0

をありがとう - それは意味があると私は理解していると信じて:その値は長い整数、したがって32ビットの長さ、したがって4バイトの長さです。したがって、括弧の参照番号は、変換するint32の配列の開始バイトです。わかった。私が持っている唯一の質問は、私の例でGPS Latitude秒のWindowsエクスプローラに表示された小数点の値が「46」だった理由です。812000000005156 "ですが、上記の[double] $ LatSecondsの積は" 46.812 "です。私の目的では実際の値はそれほど正確ではありませんが、その違いを理解したいと思います。 – osboy1

関連する問題