I tried making animated flood fill (scanline algorithm) using sleep in vb. So it will show the order of pixels being colored. It will work for a little bit but then it will return object is currently used elsewhere
This is my code
Sub AnimatedRFRecursive(ByVal P As Point, ByVal C0 As Color, ByVal C1 As Color)
Dim i, xL, xR As Integer
Dim a As Point
i = P.X
While (i >= 0 AndAlso BMP.GetPixel(i, P.Y) = C0)
Thread.Sleep(10)
BMP.SetPixel(i, P.Y, C1)
PictureBox1.Invoke(New Action(Sub() PictureBox1.Image = BMP))
i -= 1
End While
xL = i + 1
i = P.X + 1
While (i < 500 AndAlso BMP.GetPixel(i, P.Y) = C0)
Thread.Sleep(10)
BMP.SetPixel(i, P.Y, C1)
PictureBox1.Invoke(New Action(Sub() PictureBox1.Image = BMP))
End While
xR = i - 1
For i = xL To xR
If (P.Y < 349 AndAlso BMP.GetPixel(i, P.Y + 1) = C0) Then
a.X = i
a.Y = P.Y + 1
AnimatedRFRecursive(a, C0, C1)
End If
If (P.Y > 0 AndAlso BMP.GetPixel(i, P.Y - 1) = C0) Then
a.X = i
a.Y = P.Y - 1
AnimatedRFRecursive(a, C0, C1)
End If
Next
End Sub
This is how I call it
Dim thr As New Threading.Thread(Sub() AnimatedRFRecursive(point, C, Color))
thr.Start()
Please tell me where did I do wrong or if you have any other method that works also do. Thank you
You have multiple threads that need to access the same object (BMP). This will require that you synchronize access to the BMP object.
Please note that your original code has two magic numbers (500 and 349) that I assumed correspond to the bitmap's width and height. Change the usage of the variables in the code below if this assumption if incorrect.
Private BMP As Bitmap
Private BMPKey As New Object
Private Sub UpdatePictureBox()
PictureBox1.Invoke(Sub()
SyncLock BMPKey
Dim oldBM As Image = PictureBox1.Image
PictureBox1.Image = New Bitmap(BMP)
If oldBM IsNot Nothing Then oldBM.Dispose()
End SyncLock
End Sub)
End Sub
Private Function GetBMPPixel(x As Int32, y As Int32) As Color
SyncLock BMPKey
Return BMP.GetPixel(x, y)
End SyncLock
End Function
Private Sub SetBMPPixel(x As Int32, y As Int32, c As Color)
SyncLock BMPKey
BMP.SetPixel(x, y, c)
End SyncLock
End Sub
Sub AnimatedRFRecursive(ByVal P As Point, ByVal C0 As Color, ByVal C1 As Color)
Dim i, xL, xR As Integer
Dim a As Point
i = P.X
Dim width As Int32
Dim height As Int32
SyncLock BMPKey
width = BMP.Width ' original code magic number of 500
height = BMP.Height ' original code magic number of 349
End SyncLock
While (i >= 0 AndAlso GetBMPPixel(i, P.Y).ToArgb = C0.ToArgb)
Thread.Sleep(10)
SetBMPPixel(i, P.Y, C1)
UpdatePictureBox()
i -= 1
End While
xL = i + 1
i = P.X + 1
While (i < width - 1 AndAlso GetBMPPixel(i, P.Y).ToArgb = C0.ToArgb)
Thread.Sleep(10)
SetBMPPixel(i, P.Y, C1)
UpdatePictureBox()
End While
xR = i - 1
For i = xL To xR
If (P.Y < height - 1 AndAlso GetBMPPixel(i, P.Y + 1).ToArgb = C0.ToArgb) Then
a.X = i
a.Y = P.Y + 1
AnimatedRFRecursive(a, C0, C1)
End If
If (P.Y > 0 AndAlso GetBMPPixel(i, P.Y - 1).ToArgb = C0.ToArgb) Then
a.X = i
a.Y = P.Y - 1
AnimatedRFRecursive(a, C0, C1)
End If
Next
End Sub