Winapi 使用GetDIBits()获取像素RGB颜色值

Winapi 使用GetDIBits()获取像素RGB颜色值,winapi,vb6,Winapi,Vb6,我想使用GetDIBits()获取像素RGB颜色值。我已经可以使用GetPixel()获得像素RGB颜色值,但效率不高。我听说GetDIBits()在这方面做得更好 运行时没有错误,但像素的RGB值始终为0。你能指出哪里不对吗?我不熟悉Windows API 这是我的密码: Private Declare函数CreateCompatibleDC Lib“gdi32”(ByVal hdc作为Long)作为Long 私有声明函数CreateCompatibleBitmap Lib“gdi32”(By

我想使用
GetDIBits()
获取像素RGB颜色值。我已经可以使用
GetPixel()
获得像素RGB颜色值,但效率不高。我听说
GetDIBits()
在这方面做得更好

运行时没有错误,但像素的RGB值始终为
0
。你能指出哪里不对吗?我不熟悉Windows API

这是我的密码:

Private Declare函数CreateCompatibleDC Lib“gdi32”(ByVal hdc作为Long)作为Long
私有声明函数CreateCompatibleBitmap Lib“gdi32”(ByVal hdc为长,ByVal nWidth为长,ByVal nHeight为长)为长
私有声明函数selectobjectlib“gdi32”(ByVal hdc为Long,ByVal hObject为Long)为Long
私有声明函数GetDC Lib“user32”(ByVal hWnd作为Long)作为Long
私有声明函数BitBlt Lib“gdi32”(ByVal hdc为Long,ByVal x为Long,ByVal y为Long,ByVal nWidth为Long,ByVal nHeight为Long,ByVal hSrcDC为Long,ByVal xSrc为Long,ByVal ySrc为Long,ByVal操作码为Long)为Long
私有声明函数ReleaseDC Lib“user32”(ByVal hWnd为Long,ByVal hdc为Long)为Long
私有声明函数GetDeviceCaps Lib“gdi32”(ByVal hdc为Long,ByVal nIndex为Long)为Long
私有声明函数DeleteDC Lib“gdi32”(ByVal hdc作为Long)作为Long
私有声明函数DeleteObject Lib“gdi32”(ByVal hObject As Long)为Long
私有声明函数GetDIBits Lib“gdi32”(ByVal hdc为Long,ByVal hBitmap为Long,ByVal nStartScan为Long,ByVal nNumScans为Long,lpBits为Any,lpBI为BITMAPINFO,ByVal wUsage为Long)为Long
常量HORZRES为整数=8
常量VERTRES为整数=10
私有类型BitMapInfo标头
一分为二
宽度与长度相同
双倍高度
作为整数的双平面
双比特计数为整数
双压缩等长
比斯泽姆年龄一样长
双针透磁计
双倍
端型
私有类型RGBQUAD
rgbBlue作为字节
rgbGreen作为字节
RGA作为字节
RGB用作字节
端型
私有类型BITMAPINFO
bmiHeader作为BitMapInfo标头
将颜色设置为RGBQUAD
端型
专用子表单_加载()
Dim hdc尽可能长
将hDcmem变暗为长
将hBmp调暗为长
暗淡的颜色和长的颜色一样
将bmi设置为位图信息
暗淡的原始图像()如长
宽度与长度相同
低矮如长
像长一样暗的像素
作为整数的Dim r
作为整数的Dim b
作为整数的Dim g
hdc=GetDC(0)
hDcmem=CreateCompatibleDC(0)
hBmp=CreateCompatibleBitmap(hdc、宽度、高度)
oldBmp=SelectObject(hDcmem、hBmp)
宽度=GetDeviceCaps(hdc、HORZRES)
高度=GetDeviceCaps(hdc、VERTRES)
雷迪姆原始图像(宽度-1,高度-1)
使用bmi.bmi标头
.bibibitcount=32
.biCompression=biu RGB
.双翼飞机=1
.biWidth=宽度
.biHeight=高度
.biSize=Len(bmi.bmiHeader)
以
BitBlt hDcmem,0,0,宽度,高度,hdc,0,0,vbSrcCopy
获取其hDcmem、hBmp、0、身高、原始年龄(0、0)、bmi、DIB_RGB_颜色

pixel=OriginalImage(5651022)“在设置高度和宽度之前,您已经调用了CreateCompatibleBitmap函数。 您的高度和宽度为0,因此您的hbmp将永远不包含数据

常量BI_RGB和常量DIB_RGB_颜色未声明

您正在忽略32位颜色中的alpha通道,最好使用字节数组捕获单个RGB颜色

请尝试下面显示的已编辑代码

Option Explicit

Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
Private Declare Function GetDC Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function BitBlt Lib "gdi32" (ByVal hdc 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 opCode As Long) As Long
Private Declare Function ReleaseDC Lib "user32" (ByVal hWnd As Long, ByVal hdc As Long) As Long
Private Declare Function GetDeviceCaps Lib "gdi32" (ByVal hdc As Long, ByVal nIndex As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Private Declare Function GetDIBits Lib "gdi32" (ByVal hdc As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage As Long) As Long

Const HORZRES As Integer = 8
Const VERTRES As Integer = 10

Private Type BITMAPINFOHEADER
  biSize As Long
  biWidth As Long
  biHeight As Long
  biPlanes As Integer
  biBitCount As Integer
  biCompression As Long
  biSizeImage As Long
  biXPelsPerMeter As Double
  biClrUsed As Double
End Type
Private Type RGBQUAD
    rgbBlue As Byte
    rgbGreen As Byte
    rgbRed As Byte
    rgbReserved As Byte
End Type
Private Type BITMAPINFO
  bmiHeader As BITMAPINFOHEADER
  bmiColors As RGBQUAD
End Type

Private Const BI_RGB = 0&
Private Const DIB_RGB_COLORS = 0

Private Sub Form_Load()
    
    Dim hdc As Long
    Dim hDcmem As Long
    Dim hBmp As Long
    Dim oldBmp As Long
    Dim bmi As BITMAPINFO
    
    Dim OriginalImage() As Byte
    
    Dim width As Long
    Dim height As Long
    
    
    Dim r As Byte
    Dim b As Byte
    Dim g As Byte
    Dim a As Byte
   
    hdc = GetDC(0)
    hDcmem = CreateCompatibleDC(0)

    width = GetDeviceCaps(hdc, HORZRES)
    height = GetDeviceCaps(hdc, VERTRES)
    
    ReDim OriginalImage(1 To 4, width - 1, height - 1)
    hBmp = CreateCompatibleBitmap(hdc, width, height)
    oldBmp = SelectObject(hDcmem, hBmp)

    With bmi.bmiHeader
        .biBitCount = 32
        .biCompression = BI_RGB
        .biPlanes = 1
        .biWidth = width
        ' Use negative height to scan top-down.
        .biHeight = -height
        .biSize = Len(bmi.bmiHeader)
    End With

    BitBlt hDcmem, 0, 0, width, height, hdc, 0, 0, vbSrcCopy
    GetDIBits hDcmem, hBmp, 0, height, OriginalImage(1, 0, 0), bmi, DIB_RGB_COLORS
    
    r = OriginalImage(1, 565, 1022)
    g = OriginalImage(2, 565, 1022)
    b = OriginalImage(3, 565, 1022)
    a = OriginalImage(4, 565, 1022)
    
    Debug.Print "Color is - r: " & r & " g: " & g & " b: " & b

    SelectObject hDcmem, oldBmp
    DeleteObject hBmp
    DeleteDC hDcmem
    ReleaseDC 0, hdc
    
End Sub

在设置高度和宽度之前,已调用CreateCompatibleBitmap函数。 您的高度和宽度为0,因此您的hbmp将永远不包含数据

常量BI_RGB和常量DIB_RGB_颜色未声明

您正在忽略32位颜色中的alpha通道,最好使用字节数组捕获单个RGB颜色

请尝试下面显示的已编辑代码

Option Explicit

Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
Private Declare Function GetDC Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function BitBlt Lib "gdi32" (ByVal hdc 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 opCode As Long) As Long
Private Declare Function ReleaseDC Lib "user32" (ByVal hWnd As Long, ByVal hdc As Long) As Long
Private Declare Function GetDeviceCaps Lib "gdi32" (ByVal hdc As Long, ByVal nIndex As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Private Declare Function GetDIBits Lib "gdi32" (ByVal hdc As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage As Long) As Long

Const HORZRES As Integer = 8
Const VERTRES As Integer = 10

Private Type BITMAPINFOHEADER
  biSize As Long
  biWidth As Long
  biHeight As Long
  biPlanes As Integer
  biBitCount As Integer
  biCompression As Long
  biSizeImage As Long
  biXPelsPerMeter As Double
  biClrUsed As Double
End Type
Private Type RGBQUAD
    rgbBlue As Byte
    rgbGreen As Byte
    rgbRed As Byte
    rgbReserved As Byte
End Type
Private Type BITMAPINFO
  bmiHeader As BITMAPINFOHEADER
  bmiColors As RGBQUAD
End Type

Private Const BI_RGB = 0&
Private Const DIB_RGB_COLORS = 0

Private Sub Form_Load()
    
    Dim hdc As Long
    Dim hDcmem As Long
    Dim hBmp As Long
    Dim oldBmp As Long
    Dim bmi As BITMAPINFO
    
    Dim OriginalImage() As Byte
    
    Dim width As Long
    Dim height As Long
    
    
    Dim r As Byte
    Dim b As Byte
    Dim g As Byte
    Dim a As Byte
   
    hdc = GetDC(0)
    hDcmem = CreateCompatibleDC(0)

    width = GetDeviceCaps(hdc, HORZRES)
    height = GetDeviceCaps(hdc, VERTRES)
    
    ReDim OriginalImage(1 To 4, width - 1, height - 1)
    hBmp = CreateCompatibleBitmap(hdc, width, height)
    oldBmp = SelectObject(hDcmem, hBmp)

    With bmi.bmiHeader
        .biBitCount = 32
        .biCompression = BI_RGB
        .biPlanes = 1
        .biWidth = width
        ' Use negative height to scan top-down.
        .biHeight = -height
        .biSize = Len(bmi.bmiHeader)
    End With

    BitBlt hDcmem, 0, 0, width, height, hdc, 0, 0, vbSrcCopy
    GetDIBits hDcmem, hBmp, 0, height, OriginalImage(1, 0, 0), bmi, DIB_RGB_COLORS
    
    r = OriginalImage(1, 565, 1022)
    g = OriginalImage(2, 565, 1022)
    b = OriginalImage(3, 565, 1022)
    a = OriginalImage(4, 565, 1022)
    
    Debug.Print "Color is - r: " & r & " g: " & g & " b: " & b

    SelectObject hDcmem, oldBmp
    DeleteObject hBmp
    DeleteDC hDcmem
    ReleaseDC 0, hdc
    
End Sub

感谢您的患者检查我的代码并指出问题所在,代码运行正常,rgb变量返回值,但看起来值不正确(使用photoshop中的屏幕截图检查),rgb值完全相同(不应该是)。您能检查一下它有什么问题吗?您好,通过搜索和尝试,它看起来已被更改为
。biHeight=height
。biHeight=-height
原因
'使用负高度自上而下扫描。
现在rgb值返回正确,再次感谢您,我将您的回复标记为anwser。祝您一切顺利。感谢您的患者检查我的代码并指出问题所在,代码运行正常,rgb变量返回值,但看起来值不正确(使用photoshop中的屏幕截图检查),rgb值完全相同(不应该是)。您能检查一下它有什么问题吗?您好,通过搜索和尝试,它看起来已被更改为
。biHeight=height
。biHeight=-height
原因
'使用负高度自上而下扫描。
现在rgb值返回正确,再次感谢您,我将您的回复标记为anwser。祝你一切顺利。