いつもお世話になっています。
VB6を使用しています。
前回の質問でGetPixelを用いたピクセルごとのRGB値を取得することはできました。今は↓のサイトの
http://imagingsolution.blog107.fc2.com/blog-category-1.html#pagetop
VB6.0でビットマップファイルを開くのプログラムを参考にしてフォーマット解析を試みています。
BMPファイルの全体の構造も理解したつもりなのですが、画像データの所でつまづいています。
lpBits() As Byte
にデータが入っていると思われるのですが、どうすると各ピクセルの値が返ってくるのでしょうか?
'//----------------------------------------------------------------------------------------------------------
'//【関数名 】:LoadBitmapData
'//【処理概要】:ピットマップファイルデータの読込
'//【引数 】:strBitmapFileName = ビットマップのファイルネーム
'// :lpFileFeader = ビットマップファイルのBITMAPFILEHEADER(戻り)
'// :lpBitsInfo = ビットマップファイルのBITMAPINFO(戻り)
'// :lpBits() = ビットマップファイルの画像データ配列(戻り)
'//【戻り値 】:0 = 正常終了
'// :-1 = ファイル読込失敗
'//【備考 】:
'// :
'//----------------------------------------------------------------------------------------------------------
Public Function LoadBitmapData(strBitmapFileName As String, lpFileHeader As BITMAPFILEHEADER, lpBitsInfo As BITMAPINFO, lpBits() As Byte) As Long
Dim i As Integer
Dim ret As Long
Dim No As Integer
'戻り値の初期値
LoadBitmapData = -1
'ファイル名が指定されなかった場合
If (strBitmapFileName = "") Then Exit Function
If LCase(Right(strBitmapFileName, 3)) = "bmp" Then
'ファイルがビットマップファイルのとき
'ビットマップファイルをバイナリで開く
No = FreeFile()
Open strBitmapFileName For Binary As #No
Get #No, , lpFileHeader
If lpFileHeader.bfType <> &H4D42 Then ' BM
'ビットマップではない
MsgBox "ビットマップファイル形式ではありません。"
Close
Exit Function
End If
Get #No, , lpBitsInfo.bmiHeader
With lpBitsInfo.bmiHeader
If lpFileHeader.bfOffBits <> Len(lpFileHeader) + Len(lpBitsInfo.bmiHeader) Then 'カラーテーブルにデータがあるとき
'8Bit以下の場合カラーテーブルを読み込む
Get #No, , lpBitsInfo.bmiColors
End If
'ReDim lpBits(((.biWidth * .biBitCount + 31) \ 32) * 4 - 1, Abs(.biHeight) - 1) As Byte ' バイト数を計算(4バイト単位幅)
ReDim lpBits(100, 100) As Byte
End With
Seek #No, lpFileHeader.bfOffBits + 1 ' ピクセルビットのポインタへ移動
Get #No, , lpBits
Close #No
'確認の為付け足し'''''''''''''''''''''''''''''''''''''''''''''''''''
For j = 0 To Abs(.biHeight) - 1
For i = 0 To ((.biWidth * .biBitCount + 31) \ 32) * 4 - 1
Form1.Text1.SelText = lpBits(i, j) & " "
Next i
Form1.Text1.SelText = vbCrLf
Next j
End With
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
End If
'正常終了
LoadBitmapData = 0
Exit Function
LoadFileError:
'エラー処理
MsgBox "ファイル " & strBitmapFileName & " を読み込めません。"
Exit Function
End Function
text1に表示されるのは
248 0 0 0
80 0 0 0
168 0 0 0
80 0 0 0
168 0 0 0
このようになっています。
この問題は、VB6上の多次元配列が、メモリ上にどのように保持されるかを理解しなければ始まりません。
とりあえずC言語向けですが、以下のサイトが参考になるかと思います。
http://ysserve.int-univ.com/sugsi/Lecture/c2/e_04-04-04.html
http://www.e-chishiki.com/jpn/articles/programming_languages/c/arrays/memory_map_of_a_2_dimensional_array
というか、なんでもともとあった下記の行をコメントアウトしているのですか?
ReDim lpBits(((.biWidth * .biBitCount + 31) \ 32) * 4 - 1, Abs(.biHeight) - 1) As Byte ' バイト数を計算(4バイト単位幅)
この行はビットマップファイルの構造にあわせてコーディングされているのですが。
ReDim lpBits(100, 100) As Byte
これではビットマップファイルの構造に合いませんよ。
自力で解決できました。
ReDim lpBits(((.biWidth * .biBitCount + 31) \ 32) * 4 - 1, Abs(.biHeight) - 1) As Byte
をコメントアウトした理由としては自分が思っていた値が出力されなかったので理解できていない箇所を置換えでいたんです。
BMPのカラーパレットやバイトの考え方が間違っていたのでおかしな値だと思っていました。
お騒がせしました
編集 削除