Having Trouble with Pictureboxes and Lockbits

EDN Admin

Well-known member
Joined
Aug 7, 2010
Messages
12,794
Location
In the Machine
I am using Lockbits to search through screen shot to find original image. Which I load up into 2 picture boxes, 1 for screen shot and 1 for original image.

After doing the loop with Lockbits the picture boxes have a big red X in it.

If you could please look at my code and tell me what is wrong I would greatly appreciate it. Although it does find the image within the screen shot and gives a percentage but seems I can only use it 1 time before the pictureboxes dont work.
On this example I have 3 buttons, 8 labels and 4 pictureboxes
After putting them on your form, button 1 is to grab screen shot, button 2 is to load up the image and button 3 is to find the original image in the screen shot. (plus give the coordinates of the first pixel in the screen shot where the original
begins) Which works off a math equation that has to be over 60% before exiting the lockbit loop.
Any help would be greatly appreciated. Thank you in advance for any and all advice.
But after all this would be a great starting block for anyone wanting to work with lockbits or image recognition.


<pre class="prettyprint lang-vb Imports System
Imports System.Drawing
Imports System.Drawing.Graphics
Imports System.Drawing.Imaging
Imports System.Runtime
Imports System.Runtime.InteropServices
Imports System.Drawing.Drawing2D
Imports System.Windows.Forms
Imports System.Threading
Imports System.Drawing.Bitmap
Imports System.Media

Public Class Form1
Public Function GetHdc() As IntPtr
End Function
Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As IntPtr, ByVal X As Int32, ByVal Y As Int32) As Int32
Public Function GetPixel(ByVal x As Integer, ByVal y As Integer) As Color

End Function

Public Declare Auto Function SetCursorPos Lib "User32.dll" (ByVal X As Integer, ByVal Y As Integer) As Long
Public Declare Auto Function GetCursorPos Lib "User32.dll" (ByRef lpPoint As Point) As Long
Public Declare Sub mouse_event Lib "user32" Alias "mouse_event" (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long)
Public Const MOUSEEVENTF_LEFTDOWN = &H2 left button down
Public Const MOUSEEVENTF_LEFTUP = &H4 left button up
Public Const MOUSEEVENTF_MIDDLEDOWN = &H20 middle button down
Public Const MOUSEEVENTF_MIDDLEUP = &H40 middle button up
Public Const MOUSEEVENTF_RIGHTDOWN = &H8 right button down
Public Const MOUSEEVENTF_RIGHTUP = &H10 right button up
Public MessClock As Integer = 0
Const WM_SETTEXT As Int32 = 12
Const WM_KEYDOWN As Int32 = 256
Const WM_KEYUP As Int32 = 257
Const WM_SETFOCUS As Long = &H7
Dim hWnd As Long
Dim Abt As Bitmap
Dim BBt As Bitmap
Dim m_CountTo As Integer = 0 How many time to loop.

Dim xx As Int64
Dim yy As Int64
Public Enum MouseEventFlags
Fields
LEFTDOWN = 2
LEFTUP = 4
MIDDLEDOWN = 32
MIDDLEUP = 64
MOVE = 1
ABSOLUTE = 32768
RIGHTDOWN = 8
RIGHTUP = 16
WHEEL = 2048
XDOWN = 128
XUP = 256
End Enum


Public Structure Point
Public x As Integer
Public y As Integer
End Structure


Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Me.WindowState = FormWindowState.Minimized
Thread.Sleep(600)

Dim gr As Graphics
Dim bm As Image

bm = New Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb)
gr = Graphics.FromImage(bm)
gr.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, New Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height))
BBt = bm

PictureBox2.BackgroundImage = (bm)
PictureBox4.BackgroundImage = BBt
Try

Dim xXaxis As Integer
Dim yYaxis As Integer

xXaxis = 1
yYaxis = 1

Dim image1 As Image
image1 = bm

checkvalue should equal the color of pixel?

xXaxis = image1.Width - 1
yYaxis = image1.Height - 1

gr.Dispose()
Me.WindowState = FormWindowState.Normal
Catch Ex As Exception
MessageBox.Show("Cannot read file from disk. Original error: " & Ex.Message)
Finally
Check this again, since we need to make sure we didnt throw an exception on open.

End Try



End Sub


Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim Fild As New OpenFileDialog
Fild.Filter = ""
Fild.Multiselect = False
Try
If Fild.ShowDialog() = System.Windows.Forms.DialogResult.OK Then

Dim img As Image = Image.FromFile(Fild.FileName)
Dim bm As Bitmap = New Bitmap(img.Width, img.Height)
Abt = img
PictureBox1.BackgroundImage = (img)
PictureBox3.BackgroundImage = (Abt)

Label1.Text = Fild.FileName.ToString

Dim xXaxis As Integer
Dim yYaxis As Integer

xXaxis = 1
yYaxis = 1

Dim image1 As System.Drawing.Image
image1 = bm

checkvalue should equal the color of pixel?

xXaxis = image1.Width - 1
yYaxis = image1.Height - 1
Label2.Text = "X= " & xXaxis
Label3.Text = "Y= " & yYaxis
Label4.Text = "DPI Vert. & Horizontal " & image1.VerticalResolution & " " & image1.HorizontalResolution
Select Case image1.PixelFormat
Case Imaging.PixelFormat.Format24bppRgb
Label5.Text = "24 Bit RGB"
Label5.ForeColor = Color.Green
Case Imaging.PixelFormat.Format16bppArgb1555
Label5.Text = "16 Bit Argb1555"
Label5.ForeColor = Color.Red
Case Imaging.PixelFormat.Format16bppGrayScale
Label5.Text = "16 Bit Gray Scale"
Label5.ForeColor = Color.Green
Case Imaging.PixelFormat.Format16bppRgb555
Label5.Text = "16 Bit bppRgb555"
Label5.ForeColor = Color.Red
Case Imaging.PixelFormat.Format16bppRgb565
Label5.Text = "16 Bit ppRgb565"
Label5.ForeColor = Color.Red
Case Imaging.PixelFormat.Format1bppIndexed
Label5.Text = "1bppIndexed"
Label5.ForeColor = Color.Red
End Select

End If

Catch Ex As Exception
MessageBox.Show("Cannot read file from disk. Original error: " & Ex.Message)
Finally
Check this again, since we need to make sure we didnt throw an exception on open.

End Try

End Sub

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.TopMost = True


End Sub

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Dim xX As Integer
Dim yY As Integer
xX = MousePosition.X.ToString
yY = MousePosition.Y.ToString
ToolStripStatusLabel1.Text = xX & "," & yY

End Sub

Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click

Try
Dim ifnd As Boolean = False
Dim PreviousX As Integer
Dim PreviousY As Integer
PreviousX = MousePosition.X
PreviousY = MousePosition.Y
Dim MatchCount As Integer = 0



Dim oX As Integer = 0
Dim oi As Integer = 0
Dim iX As Integer = 0
Dim iY As Integer = 0
Dim bmp_original As Bitmap
Dim ImG As Bitmap
ImG = PictureBox2.BackgroundImage
bmp_original = ImG
Dim bmp_large As Bitmap
Dim SmG As Image
SmG = PictureBox1.BackgroundImage
bmp_large = SmG
Dim bmg As Bitmap
large image
ImG = BBt
small image
bmg = Abt
Thread.Sleep(1000)
large image
If BBt Is Nothing Then
Dim xbit As Bitmap = New Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height)

Dim g As Graphics = Graphics.FromImage(xbit)
BBt = xbit
g.CopyFromScreen(0, 0, 0, 0, Screen.PrimaryScreen.Bounds.Size)
g.Dispose()
Thread.Sleep(2000)
End If

small image
PictureBox3.BackgroundImage = Abt
large image
PictureBox4.BackgroundImage = BBt
For value As Integer = 0 To 5
For value As Integer = 10 To 0 Step -2
Thread.Sleep(1000)
original image
Dim oRect As New Rectangle(0, 0, bmg.Width, bmg.Height)
Dim oBmpData As BitmapData = bmg.LockBits(oRect, ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb)
Dim oPtr As IntPtr = oBmpData.Scan0
Dim oPixels(99) As Integer
Dim oMaxPix As Integer = bmg.Width + bmg.Height
Marshal.Copy(oPtr, oPixels, 0, oMaxPix)
Dim smWidth As Integer
smWidth = bmg.Width - 1
small image
PictureBox3.BackgroundImage = bmg
large image
Dim lRect As Rectangle = New Rectangle(0, 0, bmp_large.Width, bmp_large.Height)
Dim lBmpData As BitmapData = ImG.LockBits(lRect, ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb)
Dim lPtr As IntPtr = lBmpData.Scan0
Dim PixelCount As Integer = ImG.Width * ImG.Height
Dim lPixels(PixelCount - 1) As Integer
Marshal.Copy(lPtr, lPixels, 0, PixelCount)
large image
PictureBox4.BackgroundImage = ImG
Dim myPixelFormat As PixelFormat
myPixelFormat = Imaging.PixelFormat.Format24bppRgb
Dim bpp As Integer = 24
Dim zbq As Integer
zbq = lBmpData.Stride
Dim MaxScore As Integer = bmg.Height
Dim O_width As Integer
Dim O_Height As Integer
O_width = bmp_large.Width
O_Height = bmp_large.Height
Dim pixelsize As Integer = bpp / 8
Label7.Text = pixelsize

beginning of Marshal Loop
For i As Integer = 0 To lPixels.GetUpperBound(0)

If oPixels(0) = lPixels(i) Then
we have a match for top left pixel - so compare the other pixels
Dim PixelsToLeft As Integer = (i Mod ImG.Width) - 1 pixels to left of 10by10 section of large image
Dim PixelsToRight As Integer = ImG.Width - PixelsToLeft - smWidth pixels to right of 10by10 section of large image
Dim d As Integer = PixelsToLeft + PixelsToRight array distance between right edge of 10by10 section and left edge of next row
Dim MathScore As Integer

For y As Integer = 0 To 9
For x As Integer = 0 To 9
Dim oIndex As Integer = (y * 10) + x
Dim lIndex As Integer = (i + (y * (d + smWidth))) + x
If oPixels(oIndex) = lPixels(lIndex) Then
MathScore = MathScore + 1

If MathScore = Val(FormatNumber(MaxScore / 2, 0)) Then
img is the place we want to find the location at

Dim MYy As Integer
MYy = (FormatNumber(Val(lPixels(lIndex)) / Val(O_width * bpp), 0))
Label1.Text = "y: " & (FormatNumber(Val(lPixels(lIndex)) / Val(O_width * bpp), 0)) + 55
Label2.Text = "x: " & FormatNumber(Val((lPixels(lIndex) / 24) - MYy), 0)
Label3.Text = "Stride: " & FormatNumber(zbq, 0)
Dim xy As Integer = Val(Math.Floor(lPixels(lIndex) / ImG.Width * bpp))
Dim yx As Integer = (lPixels(lIndex) / 24) - MYy
Dim percent As String
Dim myDec As Decimal
inttemp = (intData2 * 100) / intData1
myDec = Val((MathScore * 100) / MaxScore)
myDec = FormatNumber(myDec, 0)
percent = myDec & "%"
Label5.Text = "Match Score: " & percent
Label6.Text = "Math Score: " & MathScore & " out of " & MaxScore
Me.ToolStripStatusLabel2.Text = "Completed"

GoTo Foundit
End If

End If


Next



Next

End If

Next

Me.Refresh()
PictureBox1.Refresh()
PictureBox2.Refresh()
PictureBox3.Refresh()

PictureBox4.Refresh()



PictureBox1.Image = (Abt)
PictureBox2.Image = (BBt)
PictureBox3.Image = (Abt)
PictureBox4.Image = (BBt)
ImG.UnlockBits(oBmpData)
bmg.UnlockBits(lBmpData)
Foundit:
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
Catch
End Try


End Sub



End Class[/code]
<br/>


View the full article
 
Back
Top