由于程序需要多次遍历屏幕查找红色点的坐标,我用GetPixel感觉速度太慢,且CPU占用率猛升至100%。特寻求高效方法,请举例说明,谢谢!

解决方案 »

  1.   

    给你个思路吧:一、先把屏幕采用截图的方式写到一个hdc中
    二、然后使用GetBitmapBits或GetDIBits将颜色信息存入数组
    三、对数组进行检查应该快得多了。
      

  2.   

    //给你个思路吧://一、先把屏幕采用截图的方式写到一个hdc中
    //二、然后使用GetBitmapBits或GetDIBits将颜色信息存入数组
    //三、对数组进行检查应该快得多了。但是屏幕不断变化的
      

  3.   

    Option ExplicitPrivate Type POINTAPI
        x As Long
        y As Long
    End Type
    Private 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
    Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
    Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
    Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long
    Private Declare Function ScreenToClient Lib "user32" (ByVal hwnd As Long, lpPoint As POINTAPI) As Long
    Private Declare Function WindowFromPoint Lib "user32" (ByVal xPoint As Long, ByVal yPoint As Long) As LongPrivate Sub Timer1_Timer()
        Static lX As Long, lY As Long
        On Local Error Resume Next
        
        
        Dim P As POINTAPI, h As Long, hD As Long, r As Long
        GetCursorPos P
        If P.x = lX And P.y = lY Then Exit Sub
        lX = P.x: lY = P.y
        lblData(0).Caption = "x:" & lX & ",y:" & lY
        h = WindowFromPoint(lX, lY)
        lblData(1).Caption = h
        hD = GetDC(h)
        lblData(2).Caption = hD
        ScreenToClient h, P
        lblData(3).Caption = "x:" & P.x & ",y:" & P.y
        r = GetPixel(hD, P.x, P.y)
        
        If r = -1 Then
            BitBlt Picture1.hdc, 0, 0, 1, 1, hD, P.x, P.y, vbSrcCopy
            r = Picture1.Point(0, 0)
        Else
            Picture1.PSet (0, 0), r
        End If
        
        lblData(4).Caption = Hex$(r)
        Picture1.BackColor = r
       Me.Text1.Text = r
    End Sub
      

  4.   

    谢谢你的参与, flyingZFX(★我飞★我飞★我飞呀飞★)
    不过我要的不是这个!
      

  5.   

    使用DIB方法来取得屏幕上的图像:
    Private 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 LongPrivate Declare Function StretchDIBits Lib "gdi32" (ByVal hdc As Long, ByVal XDest As Long, ByVal YDest As Long, ByVal nDestWidth As Long, ByVal nDestHeight As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, lpBits As Any, lpBitsInfo As Any, ByVal wUsage As Long, ByVal dwRop As Long) As LongPrivate Declare Function CreateDIBitmap Lib "gdi32" (ByVal hdc As Long, lpbmih As Any, ByVal fdwInit As Long, lpbInit As Any, lpbmi As Any, ByVal fuUsage As Long) As LongPrivate Declare Function CreateDIBSection Lib "gdi32" (ByVal hdc As Long, lpbmi As Any, ByVal iUsage As Long, ByRef ppvBits As Long, ByVal hSection As Long, ByVal dwOffset As Long) As LongPrivate Declare Function GetDIBits Lib "gdi32" (ByVal hdc As Long, ByVal hbmp As Long, ByVal uStartScan As Long, ByVal cScanLines As Long, lpvBits As Any, lpbmi As Any, ByVal uUsage As Long) As LongPrivate Declare Function SetDIBits Lib "gdi32" (ByVal hdc As Long, ByVal hbmp As Long, ByVal uStartScan As Long, ByVal cScanLines As Long, lpvBits As Any, lpbmi As Any, ByVal uUsage As Long) As LongPrivate Declare Function GetDIBColorTable Lib "gdi32" (ByVal hdc As Long, ByVal uStartIndex As Long, ByVal cEntries As Long, pColors As RGBQUAD) As LongPrivate Declare Function SetDIBColorTable Lib "gdi32" (ByVal hdc As Long, ByVal uStartIndex As Long, ByVal cEntries As Long, pColors As RGBQUAD) As LongPrivate Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSrc As Any, ByVal ByteLen As Long)Private Declare Function GetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As LongPrivate Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As LongPrivate Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As LongPrivate 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 LongPrivate Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As LongPrivate Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As LongPrivate Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long) As LongPrivate Declare Function timeGetTime Lib "winmm.dll" () As LongPrivate Type BitmapInfoHeader '文件信息头——BITMAPINFOHEADER
        biSize As Long            
        biWidth As Long           
        biHeight As Long          
        biPlanes As Integer       
        biBitCount As Integer     
        biCompression As Long     
        biSizeImage As Long       
        biXPelsPerMeter As Long   
        biYPelsPerMeter As Long   
        biClrUsed As Long         
        biClrImportant As Long    
    End TypePrivate Type RGBQUAD          '调色板,只有biBitCount等于1、4、8时才有调色板。
        rgbBlue As Byte           'rgbBlue 蓝色分量
        rgbGreen As Byte          'rgbGreen 绿色分量
        rgbRed As Byte            'rgbRed 红色分量
        rgbReserved As Byte       'rgbReserved# 保留,=0
    End TypePrivate Type BITMAPINFO
            bmiHeader As BitmapInfoHeader
            bmiColors As RGBQUAD
    End TypePrivate BmpInfo As BitmapInfoHeader
    Private LineBytes As Long  '一个扫描行的长度
    Private MapData() As Byte  '图象数据
    Dim ColOut() As Long
    Dim InPutHei As Long
    Dim InPutWid As Long
    Dim OutPutHei As Long
    Dim OutPutWid As LongPublic Sub MemGet(ByVal IdSource As Long, XBegin As Long, ByVal YBegin As Long, ByVal XEnd As Long, ByVal YEnd As Long)
    Dim bi24BitInfo As BITMAPINFO
    Dim iBitmap As Long
    Dim I As Long
    Dim L As Long
    Dim X As Long
    Dim Y As Long
    Dim W As Long
    Dim H As Long
    Dim AlignedW As Long 'in bytesInPutWid = XEnd - XBegin
    InPutHei = YEnd - YBegin
    W = InPutWid + 1
    H = InPutHei + 1
    AlignedW = ((W * 3& + 3&) And (Not 3&))
    ReDim ColOut(InPutWid, InPutHei, 2&)
    ReDim MapData(AlignedW * H - 1)
    With bi24BitInfo.bmiHeader
       .biBitCount = 24
       .biCompression = 0&
       .biPlanes = 1
       .biSize = Len(bi24BitInfo.bmiHeader)
       .biWidth = W
       .biHeight = H
    End With
    iBitmap = GetCurrentObject(IdSource, 7&)  '获取对象
    GetDIBits IdSource, iBitmap, 0&, H, MapData(0), bi24BitInfo, 0& '获取图形
    For Y = 0& To InPutHei  '转换一维数组到三维数组
       L = Y * AlignedW      '此句提前,否则会遗漏一行像素的数据
       For X = 0& To InPutWid
             ColOut(X, Y, 2&) = MapData(L)      'Blue
             ColOut(X, Y, 1&) = MapData(L + 1&) 'Green
             ColOut(X, Y, 0&) = MapData(L + 2&) 'Red
             L = L + 3&
       Next
    NextDeleteObject iBitmap  '此处删除对象
    End Subsub command1_click
    MemGet getdc(0),0,0,screen.width,screen.height '调用过程,获取屏幕图像
    '此时屏幕上的各个点的像素值已经被分解并保存在数组ColOut中了,
    '该三维数组的定义:ColOut(A,B,C) A: X坐标;B:Y坐标;C:从0-2依次为红绿篮三色的值。
    '写个二次循环来编历数组,通过判断数组的最后一项元素,就可以知道是否为红色的点了。
    end sub原贴见:http://community.csdn.net/Expert/topic/3252/3252001.xml?temp=.3943598