上へ M0101 JPGサイズの獲得 M0105 EXIFメーカノートを読む
| |
VB.NET2005 TIPS /
マルチメディア系 |
M0105 EXIFメーカノートを読む |
最終更新:2007/02/20
更新再掲 |
●解説
標準のTag情報以外に、メーカ独自の情報が許されており、それがメーカノートと呼ばれるTagである。この部分は非公開なので、自分で試行錯誤して解析する必要があるが、重要な情報が含まれている場合がある。形式は任意なので、一般的には得ることはできなく、メーカ毎の対応が必要となる。ここでは、NIKON
D70s のメーカノートの例を紹介する。
●原理
メーカノートのTag値は&H927Cで、多分、必ず含まれている。PropertyItemクラスでは、Typeが7(任意)でその全てのデータがバイト配列でValueとして得られる。
●方法
サイズと値(バイト値列)は標準コードで簡単に得られるので、後は、メーカ毎にそのバイト配列を解釈して行く。
NIKON
D70sでは、この部分もIFD形式となっており、独自のTagで構成されているが、IFDとして標準的に処理ができる。データの先頭18バイトはTiffヘッダになっており、ここに、ここのデータのバイトオーダを示すコード"II"または"MM"がある。従って、以降のポインタはこのコードの位置が基準になる。
メーカノートTag(h927C、図では、7C92)と、メーカノート部分(青矢印の先)
NIKONメーカノートは、インテル形式である。
●実例
ここでは、L4002 EXIFInfoを利用した例である。
frgT は私製グリッドコントロール
濃緑部分が、EXIFInfoクラス
Imports System.IO
Imports ExifInfo.ExifInfo
Imports System.Drawing.Imaging
Dim BB(), B() As Byte
Dim RD() As Object
Dim MED As ExifInfo.Endian
Dim i, j, Cnt, DCnt As Integer
Dim pi As PropertyItem = bmp.GetPropertyItem(TagNo("メーカノート"))
BB = pi.Value
Cnt = pi.Len
If AsciiByteToString(BB, 0, 6) = "NIKON"
Then
'NIKONのヘッダチェック
Dim ED As String = AsciiByteToString(BB,
10, 2) 'バイトオーダを得る
Select Case ED
Case "II"
MED = ExifInfo.Endian.II
Case "MM"
MED = ExifInfo.Endian.MM
Case Else
MsgBox("メーカノートが不正です。",
MsgBoxStyle.Critical)
Exit Sub
End Select
Dim IFDP As Integer = 10 + 8
'オフセットは固定でOK
Dim IFDC As Integer = UInt16ByteToInteger(BB,
IFDP, MED) 'IFDの個数
Dim Tag, BC, BCnt As Integer
Dim Type As ExifInfo.ValueType
Dim L, V As Long
frgT.BeginUpdate()
frgT.SetGridConstruction(8, IFDC + 1, 2, 1)
frgT.RowHeader(0) = HdrM
For i = 0 To IFDC - 1
frgT(0, i + 1) = i + 1
Tag =
UInt16ByteToInteger(BB, IFDP + 2 + 12 * i + 0, MED)
'NIKON独自のTag番号
frgT(1, i + 1) = Tag
frgT(2, i + 1) = Hex(Tag)
Type =
UInt16ByteToInteger(BB, IFDP + 2 + 12 * i + 2, MED) 'データ型
frgT(3, i + 1) = CInt(Type)
frgT(4, i + 1) =
TypeName(Type)
L = UInt32ByteToLong(BB,
IFDP + 2 + 12 * i + 4, MED)
'データ数
frgT(5, i + 1) = L
BC = UnitByteCount(Type)
BCnt = L * BC
frgT(6, i + 1) = BCnt
If BCnt > 4 Then '値はポインタ
V =
UInt32ByteToLong(BB, IFDP + 2 + 12 * i + 8, MED) + 10
'ポインタ算出
Else
V = IFDP + 2 + 12 * i + 8
End If
ReDim B(BCnt - 1)
For j = 0 To BCnt - 1
If BB.Length <= (V + j) Then
Exit For 'NIKON バグ対策
B(j) = BB(V + j)
'データをバイト配列にする
Next
ByteToRawData(Type,
BCnt, B, MED, RD, DCnt)
'以下は、表示用の文字列を生成しているコード
Dim D As String
Select Case Type
Case ExifInfo.ValueType.Any,
ExifInfo.ValueType.Ascii, ExifInfo.ValueType.SByte, ExifInfo.ValueType.Ubyte
frgT(7, i +
1) = RD(0)
Case ExifInfo.ValueType.Int16,
ExifInfo.ValueType.Int32, ExifInfo.ValueType.UInt16, ExifInfo.ValueType.UInt32
D = ""
D =
CLng(RD(0)).ToString
For j = 1 To
DCnt - 1
D = D + ", " + CLng(RD(j)).ToString
Next
frgT(7, i +
1) = D
Case ExifInfo.ValueType.Int32R,
ExifInfo.ValueType.Uint32R
D = ""
D =
CLng(RD(0)).ToString + "/" + CLng(RD(1)).ToString + "(" + CDbl(RD(0) /
RD(1)).ToString + ")"
For j = 1 To
DCnt \ 2 - 1
D = D + ", " + CLng(RD(2 * j)).ToString + "/" + CLng(RD(2 * j + 1)).ToString +
"(" + CDbl(RD(2 * j) / RD(2 * j + 1)).ToString + ")"
Next
frgT(7, i +
1) = D
End Select
Next
frgT.ColTextAlign(2) = FreeGrid.TextAlign.Right
frgT.EndUpdate()
Else
MsgBox("メーカノートが不正です。", MsgBoxStyle.Critical)
End If
上記コードで読んだメーカノート
|