关于SetDIBitstoDevice函数的儗问

来源:互联网 发布:人工智能世界知乎 编辑:程序博客网 时间:2024/05/16 00:27

最近在用VB做图像处理,因为害怕速度慢慢,所以就没有用自带的图像处理函数,转而用API函数来做,于是就用到了SetDIBitstoDevice做图像输出函数,但在实际情况下,遇到一个很奇怪的问题,原本想在图像对角线输出一个蓝线,却意外地出现了两个平行的斜线,而非一条对角线。我定义的是24位图,以下是我的代码:

    Public Type BmpHeader '文件信息头——BITMAPINFOHEADER
     bmSize As Long       '本结构所占用字节数(14-17字节)
     bmWidth As Long      '位图的宽度,以像素为单位(18-21字节)
     bmHeight As Long     '位图的高度,以像素为单位(22-25字节)
     bmPlanes As Integer  '目标设备的级别,必须为1(26-27字节)
     bmBitCount As Integer '每个像素所需的位数,必须是1(双色),(28-29字节) , 4(16色), 8(256色) 或 24(真彩色)之一
     bmCompression As Long  '位图压缩类型,必须是 0 (不压缩),(30-33字节) , 1(BI_RLE8压缩类型)或 2(BI_RLE4压缩类型)之一
     bmSizeImage As Long    '位图的大小,以字节为单位(34-37字节)
     bmXPelsPerMeter As Long  '位图水平分辨率,每米像素数(38-41字节)
     bmYPelsPerMeter As Long  '位图垂直分辨率,每米像素数(42-45字节)
     bmClrUsed As Long         '位图实际使用的颜色表中的颜色数(46-49字节)
     bmClrImportant As Long    '位图显示过程中重要的颜色数(50-53字节)
    End Type
'*************************************************
    Public Type RGB     '定义RGB色信息.在BMP中是以BGR顺序存储的.
     Bb As Byte
     Gg As Byte
     Rr As Byte
     rgbReserved As Byte
    End Type
'***********************************************
    Public Type BitMap
             bHeader As BmpHeader
             bColors As RGB
            
    End Type
'***********************************************************************************
Public SurfHandle As Long
Public pBufdata() As Byte   '图像数据数组
Declare Function SetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long
'删除一个DC
Public Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
'删除一个对象
Public Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
'选择当前对象
Public Declare Function GetCurrentObject Lib "gdi32" (ByVal hdc As Long, ByVal uObjectType As Long) As Long
'获取DIB
Public Declare Function GetDIBits Lib "gdi32" (ByVal aHDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BitMap, ByVal wUsage As Long) As Long
'获取系统时间
Public Declare Function timeGetTime Lib "winmm.dll" () As Long
'输出位图
Public Declare Function SetDIBitsToDevice Lib "gdi32.dll" (ByVal hdc As Long, ByVal XDest As Long, ByVal YDest As Long, ByVal dwWidth As Long, ByVal dwHeight As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal uStartScan As Long, ByVal cScanLines As Long, lpvBits As Any, lpbmi As Any, ByVal fuColorUse As Long) As Long
'内存拷贝
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSrc As Any, ByVal ByteLen As Long)
'********************************************************************
Public Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long

'********************************************************************************************
    Public bit24 As BitMap '定义BMP信息
    Public ColVal() As Byte '用于存放从DIB输入的像素值
    Public Colout() As Byte '用于存放向DIB输出的像素值
    Public nbmp1() As Long   '图像处理用的数组
   
    Public inh As Long '用于记录输入图像的高度
    Public inw As Long '用于记录输入图像的宽度
    Public OH As Long    '要插值的目标高度
    Public OW As Long   '要插值的目标宽度
   ' Public bit As Integer
    Dim R As Long                 '用于保存红色分量
    Dim G As Long                '用于保存绿色分量
    Dim B As Long                 '用于保存蓝色分量
    Public Const Bits As Long = 32

’*************************************************

'在这个过程中所用到的只是一些参数的设定和API的调用,不涉及算法。
'过程二:     图像输出的过程:
    Public Sub DIBPut(ByVal IdDestination As Long, ByVal W As Long, ByVal H As Long)
    On Error GoTo ErrLine
'    W = INW '+ 1
'    H = INH '+ 1
   
    With bit24.bHeader
'**************************************
        .bmBitCount = 24             '位图宽度,在这里图像采集卡的位图是24位,非32位   " .bmBitCount = 32   "改成24
        .bmCompression = 0&
        .bmPlanes = 1
        .bmSize = Len(bit24.bHeader)
'**********************************
        .bmWidth = W
        .bmHeight = H
         LineBytes = ((W * Bits + 31) And &HFFFFFFE0) / 8
        .bmSizeImage = LineBytes * H
    End With
'    SetDIBitsToDevice IdDestination, 0, 0, W, H, 0, 0, 0, H, ColOut(0, 0, 0), bi24BitInfo.bmiHeader, 0
     SetDIBitsToDevice IdDestination, 0, 0, W, H, 0, 0, 0, H, Colout(0, 0, 0), bit24.bHeader, 0  'DIB_PAL_COLOR 'DIB_RGB_COLORS
    Exit Sub
ErrLine:
    MsgBox Err.Description
    End Sub

Private Sub Command1_Click()
inw = 300
inh = 300
'  With Picture1
'    .ScaleMode = 3
'    .BorderStyle = 0
'    DibGet Picture1, 0, 0, .ScaleWidth - 1, .ScaleHeight - 1
'  End With
  ReDim Colout(2, inw, inh) As Byte         ’这里是24位,因些,第一维上界为2,如果是32位,则为3
Dim i As Integer, j As Integer
    For i = 0 To inw - 1
        For j = 0 To inh - 1
            If j = i Then '* (inh / inw)
                Colout(0, i, j) = 255
                Colout(1, i, j) = 0
            'Else
                'Colout(2, i, j) = 255
            End If
        Next
    Next
'    CopyData inw, inh
 '
            Picture2.ScaleMode = 3
            Picture2.Width = inw * 15
            Picture2.Height = inh * 15
            'Picture2.AutoSize = True
            Picture2.AutoRedraw = True
            'Picture2.BorderStyle = 0
         Picture2.Cls
    DIBPut Picture2.hdc, inw, inh

End Sub