Solved

# detect a image (sprite) in a bitmap

Posted on 2006-05-10
351 Views
Hello,

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.
0
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 :~)

0

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.
0

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\\
'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)
FirstPixel = tmpPixel1
FirstPoint.x = x
FirstPoint.y = y
GoTo Coolz0rz
End If
Next x
Next y
Coolz0rz:
'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 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
Exit Function
End If
NextX:
Next x
NextY:
Next y
mousexy.x = -1
End Function
'\\Code//
0

## Featured Post

Introduction In a recent article (http://www.experts-exchange.com/A_7811-A-Better-Concatenate-Function.html) 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…