detect a image (sprite) in a bitmap

Posted on 2006-05-10
Last Modified: 2013-12-03

i got the following situation,

i got a picture in a picturebox that is a bitmap of size 800x600

this picture is a table of 8 x 4 cells ; in one of the cells of this table a image (sprite) can be situated.  The dimension of this image (sprite) are 32x32 pixels.

eg. empty table                                                eg. fille  table

------------------------------------                     ------------------------------------                    
|    |    |    |    |    |    |    |    |                    |    |    |    |    |    |    |    |    |
------------------------------------                     ------------------------------------                    
|    |    |    |    |    |    |    |    |                    |    |    |    |    | X |    |    |    |
------------------------------------                     ------------------------------------                    
|    |    |    |    |    |    |    |    |                    |    |    |    |    |    |    |    |    |
------------------------------------                     ------------------------------------                    
|    |    |    |    |    |    |    |    |                    |    |    |    |    |    |    |    |    |
------------------------------------                     ------------------------------------                    

i want to write a script that detect the position were the sprite is located in the screen

there will only be 1 sprite situated in a picture and the detection should takes less than 15 seconds per image.

can somebody help me with this.

I have already been doing bitblt's and xoring the image .. but i can't sort it out how to DETECT or pinpoint the position were the SPRITE is located in the grid-picture.
Question by:justroll
    LVL 17

    Accepted Solution

    The quickest way to do this is to use a DMA (direct memory access) approach.  It is possible to map an array to the memory use by a copy of your empty image and also map an array to the memory used by the image you want to scan.

    Once you have mappaed the arrays to the images to can loop through the arrays and compare If A(x,y)<>B(x,y) Then you have found the sprite.

    The process will take less than 2 seconds.

    An example of this process and some other links a comments can be found here:

    I adapted the example to map a UDT array to the picture's memory so if you want to work with individual pixels like this A(x,y).Red, A(x,y).Blue or A(x,y).Green. So in a blink you can apply filters, make images monochrome, etc.

    Hope this helps :~)

    LVL 29

    Expert Comment

    Could you post the actuall image on a webserver so anyone who wants to try this may use your image as a stepping stone.
    LVL 1

    Assisted Solution

    The above would most likely be the fastest way. Though another method is to use GetPixel in a loop, slightly slower, but I'd think it woul dbe easiear to implement. Choose whatever suits your needs the best.

    'Code requires nothing. Reccomended to be placed inside a module
    Public Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long
    Public Declare Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long
    Public Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
    Public Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
    Public Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
    Public Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
    Public Declare Function SetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal crColor As Long) As Long
    Public Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
    End Type
    Public Type POINTAPI
        x As Long
        y As Long
    End Type

    Public Function FindBitmapMask(SBitmapDC As Long, PBitmapDC as Long, posx1 As Long, posy1 As Long, posx2 As Long, posy2 As Long, MaskColor As Long) As POINTAPI
    Dim x As Long, x2 As Long, y As Long, y2 As Long, tmpPixel1 As Long, tmpPixel2 As Long, PBitmapDC As Long, mousexy As POINTAPI, FirstPixel As Long, FirstPoint As POINTAPI

    For y = 0 To Form1.Image1.Height - 1
        For x = 0 To Form1.Image1.Width - 1
        tmpPixel1 = GetPixel(SBitmapDC, x, y)
        If tmpPixel1 <> MaskColor Then
            FirstPixel = tmpPixel1
            FirstPoint.x = x
            FirstPoint.y = y
            GoTo Coolz0rz
        End If
        Next x
    Next y
    'MsgBox FirstPoint.x & "," & FirstPoint.y
    For y = posy1 To posy2
        For x = posx1 To posx2
        tmpPixel1 = GetPixel(PBitmapDC, x, y)
        If tmpPixel1 = FirstPixel Then
            For y2 = y - FirstPoint.y To y + Form1.Image1.Height - 1 - FirstPoint.y 'Image1 is the quick and lazy way
                For x2 = x - FirstPoint.x To x + Form1.Image1.Width - 1 - FirstPoint.x ' to get height and width, lol
                    tmpPixel1 = GetPixel(PBitmapDC, x2, y2)
                    tmpPixel2 = GetPixel(SBitmapDC, x2 - (x - FirstPoint.x), y2 - (y - FirstPoint.y))
                    If tmpPixel2 <> MaskColor Then
                        If tmpPixel1 <> tmpPixel2 Then GoTo NextX
                    End If
                    'SetPixel Form1.Picture2.hdc, x2, y2, 300000
                Next x2
            Next y2
            mousexy.x = x - FirstPoint.x
            mousexy.y = y - FirstPoint.y
            FindBitmapMask = mousexy
            Exit Function
        End If
        Next x
    Next y
    mousexy.x = -1
    FindBitmapMask = mousexy
    End Function

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    IT, Stop Being Called Into Every Meeting

    Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

    Introduction In a recent article ( for the Excel community, I showed an improved version of the Excel Concatenate() function.  While writing that article I realized that no o…
    Introduction While answering a recent question about filtering a custom class collection, I realized that this could be accomplished with very little code by using the ScriptControl (SC) library.  This article will introduce you to the SC library a…
    Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
    Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

    779 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    18 Experts available now in Live!

    Get 1:1 Help Now