VB2005でAPI関数 GetDIBitsを使用する方法をおしえてください。

タグの編集
投稿者 YAYA  (社会人) 投稿日時 2009/10/31 06:37:15
インターネットでしらべたのですが、全然動作しません。お願いします。
Declare Function GetDIBits Lib "gdi32.dll" (ByVal hdc As Integer, ByVal hbmp As Integer, ByVal uStartScan As Integer, _
ByVal cScanLines As Integer, lpvBits As Integer, lpbi As BITMAPINFO, _
ByVal uUsage As Integer) As Integer



Dim bmp As BITMAP, x As Long, y As Long
       
        Dim w As Integer, h As Integer
        Dim Pic As Integer()
        Dim TextureImg As Integer
        Dim bi24BitInfo As New BITMAPINFO


        If Dir(Filename) = "" Then
            MsgBox("loadBMP: file not found.")
            End
        End If


        With Pict
            .Image = Image.FromFile(Filename)

            .Refresh()
            w = .ClientSize.Width
            h = .ClientSize.Height


        End With
        


        With bi24BitInfo.bmiHeader
            .biBitCount = 24
            .biCompression = 0
            .biPlanes = 1
            .biSize = Len(bi24BitInfo.bmiHeader)
            .biWidth = w
            .biHeight = h
           
        End With
  GetDIBits(Pict.CreateGraphics.GetHdc.ToInt32, Pict.Handle, 0, h, TextureImg, bi8BitInfo, 0)
投稿者 ?-?  (その他) 投稿日時 2009/10/31 06:49:06
プログラムは書いたとおりに動作するって誰かが言ってたな・・・

それはともかく、どういう動作にさせたいのかなぁ?
投稿者 (削除されました)  () 投稿日時 2009/10/31 07:41:28
(削除されました)
投稿者 (削除されました)  () 投稿日時 2009/10/31 07:43:31
(削除されました)
投稿者 あにす  (社会人) 投稿日時 2009/10/31 07:44:53
単純なAPI呼び出しではないため、凄く大変だと思います。
もしマネージコードで実現出来る仕様ならAPIの使用を避けてマネージコードで書いた方がいいと思います。
そこら辺の事情を書いたら誰かが力になってくれるかも?

というのもなんなので、宣言だけ書いてみました。動作確認してないのでどっかに間違いがあると思いますが、ここまで書くだけでもちょっと大変なので…。

Declare Function GetDIBits Lib "gdi32.dll" ( _
    ByVal hdc As IntPtr, _
    ByVal hbmp As IntPtr, _
    ByVal uStartScan As UInteger, _
    ByVal cScanLines As UInteger, _
    ByVal lpvBits As IntPtr, _
    ByRef lpbi As BITMAPINFO, _
    ByVal uUsage As UInteger) _
As Integer

Public Structure BITMAPINFO
    Public bmiHeader As BITMAPINFOHEADER
    Public bmiColors() As RGBQUAD
End Structure

Public Structure BITMAPINFOHEADER
    Public biSize As UInteger  ' 構造体サイズ==40 
    Public biWidth As Integer '画像横幅 
    Public biHeight As Integer '画像高さ 
    Public biPlanes As UInt16   ' ==1(Windows初期の名残) 
    Public biBitCount As UInt16 'カラービット数(1, 4, 8, 16, 24, 32) 
    Public biCompression As UInteger       ' 圧縮コード(BI_RGB, BI_RLE4, BI_RLE8, BI_BITFIELDSのいずれか) 
    Public biSizeImage As UInteger 'イメージのバイト数 
    Public biXPelsPerMeter As Integer     '水平解像度 
    Public biYPelsPerMeter As Integer     '垂直解像度 
    Public biClrUsed As UInteger  'カラーテーブルの数 
    Public biClrImportant As UInteger '重要な色の数 
End Structure

Public Structure RGBQUAD
    Public rgbBlue As Byte
    Public rgbGreen As Byte
    Public rgbRedas As Byte
    Public rgbReserved As Byte
End Structure


【参考URL】
プラットフォーム呼び出しのデータ型
http://msdn.microsoft.com/ja-jp/library/ac7ay120(VS.80).aspx

GetDIBits 関数
http://msdn.microsoft.com/ja-jp/library/cc428673.aspx

伝説のお茶の間 BITMAP ビットマップ 構造体
http://dencha.ojaru.jp/programs_07/pg_graphic_structs.html
投稿者 YAYA  (社会人) 投稿日時 2009/10/31 20:45:50
返答ありがとうございます。
早速ためしてみます。
APIにこだわるのは環境が限られているため、出来るだけAPIで行いたいの
画像スクロールを作成したいのでできるだけ高速化したいためです。
GetBitmapBitsもためしましたが、うまくできず。GetDIBitsを試しているところです。
LockBits、Marshal?はうまく動作したのですが速度がいまいちでした。
よろしければ、GetBitmapBitsもおしえてください。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2009/10/31 20:57:21
スクロールが必要な場合には、TextureBrush クラスを試してみてください。
比較的高速に描画する事ができるかと思います。

http://dobon.net/cgi-bin/vbbbs/cbbs.cgi?mode=al2&namber=23844&no=0&KLOG=2
投稿者 YAYA  (社会人) 投稿日時 2009/11/1 06:44:33
TextureBrush作成しました。とても早く処理ができました。
魔界の仮面弁士様ありがとうございました。
投稿者 YAYA  (社会人) 投稿日時 2009/11/2 06:52:02
System.Environment.TickCount - t1で速度UPしらにですが、描写が早くなりません。
なぜでしょうか?
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2009/11/2 18:37:48
> System.Environment.TickCount - t1で速度UPしらにですが、描写が早くなりません。
? ごめんなさい、意味が分かりませんでした。


現象を再現可能なコードを提示して頂いていないので、遅い原因となっている
問題点を指摘することはできませんが、PictureBox を使うのであれば、
下記の点に気をつけてみてください。

・基本的に CreateGraphics は使わないこと。Paint イベントの e.Graphics を使うか、もしくは
 Graphics.FromImage で描画した Bitmap クラスを Image/BackgroundImage に渡すようにする。
・Paint イベントを使う場合には、「Invalidate メソッド」「Update メソッド」「Refresh メソッド」を
 正しく使い分ける事。Refresh は時間がかかる処理なので、短時間に連続して呼び出すべきではない。
・TickCount は、いわゆる「24.9 日問題」を含みます。通常はそれでも問題ありませんが、
 ミリ秒程度の時刻差を測定する場合には、Stopwatch クラスや DateTime.Now の利用も検討を。
・描画結果の高速書き換えが期待通りに行かない場合には、ダブルバッファリングを試してみてください。
投稿者 YAYA  (社会人) 投稿日時 2009/11/3 03:54:49
魔界の仮面弁士様、ご返答ありがとうございます。早速、ためしてみます。
投稿者 YAYA  (社会人) 投稿日時 2009/11/3 04:50:59
魔界の仮面弁士様、ありがとうございました。
Paint イベントの e.Graphicsとダブルバッファリングを行ったところ、速度がはやなりました。
本当にありがとうございました。