VB.NET2005 TIPS / マルチメディア系 |
M0101 JPGサイズの獲得 |
最終更新:2006/11/12 再掲 |
●解説
JPEGファイルの画像サイズは、Imageとして読めば得ることができるが、画像ファイルを全て読み込むので時間が掛かる。ここでは、画像ファイルの付帯情報をバイナリで読み取り直接得る方法を紹介する。EXIFあるいは、JFIF(通常のJPEGファイル)で適用できる。
●原理
EXIFやJFIFでは、画像の付帯情報が内包されており、マーカの hFFC0
で始まる領域に以下のように記録されている。
hFFC0 hSSSS hPP hYYYY
hXXXX h・・・・
hSSSS:このブロックのサイズ(SSSSの2バイトを含む)
hPP:画像情報の一種
hYYYY:画像の縦のピクセルサイズ
hXXXX:画像の横のピクセルサイズ
●方法
○形式
一般に、マーカの位置は不定なので、頭から手繰って探す必要がある。この場合は、一括に読むより、ストリームとしてバイト単位で逐次読む方が効率的である。Streamオブジェクトにてマーカを確認しながら読み取る。SeekおよびReadByteメソッドを使用する。マーカについては、ここを参照。
○手順
-
SOIマーカ(Start Of Image):hFFD8 を確認する。
-
APPマーカ:hFFE0(APP0:JFIF)、hFFE1(APP1:EXIF) を確認する。
-
上記がOKの場合は、hFFC0 を探し、あれば、画像サイズを読む。
●実例
Dim P As Long
'ストリームのポインタ
Dim W, H As Integer
Dim F As String = ファイルへのパス
Dim st As Stream = File.Open(F, FileMode.Open, FileAccess.Read)
If CheckJFIF(st) Then
Select Case Marker(st)
Case "FFE0"
FT = "JFIF"
Case "FFE1"
FT = "EXIF"
Case Else
FT = "不明"
End Select
If FT <> "不明" Then
st.Seek(P,
SeekOrigin.Current)
If GetSize(st, W, H)
Then
→画像サイズ獲得
Else
→画像サイズ不明
End If
Else
→JPEGファイルではない
End If
Else
→画像ファイルではない
End If
st.Close()
この例では、マーカは16進数の文字列に変換している。
ReadByteは1バイト読み込んで、Integerにし、ポインタを自動的に進めるものである。
(バッファリングやキャッシングはシステム側で自動的に行われる)
'ローカルな関数
Private Function CheckJFIF(ByVal st As Stream) As
Boolean
If Hex(st.ReadByte) = "FF" Then
If Hex(st.ReadByte) = "D8" Then
Return True
End If
End If
Return False
End Function
Private Function GetSize(ByVal st As Stream,
ByRef W As Integer, ByRef H As Integer) As Boolean
Dim ff As Integer = 0
Dim MK As String
While ff = 0
MK = Marker(st)
Select Case MK
Case "FFC0"
st.Seek(1,
SeekOrigin.Current) '1バイト読み飛ばす
H = st.ReadByte * 256
H = H +
st.ReadByte
W =
st.ReadByte * 256
W = W +
st.ReadByte
Return True
Case "FFD9"
Return False
'hFFC0見つからず
Case Else
st.Seek(P,
SeekOrigin.Current) '次のマーカの先頭に行く
End Select
End While
Return False
End Function
'マーカとそのサイズを獲得する。
Private Function Marker(ByVal st As Stream) As
String
Dim M As String
M = Hex(st.ReadByte)
M = M + Hex(st.ReadByte)
If M <> "FFD9" Then
P = st.ReadByte * 256
P = P + st.ReadByte - 2
End If
Return M
End Function
|