制作洪水填充动画 vb return object is currently used elsewhere using thread.sleep
Making animation of flood fill in vb return object is currently used elsewhere using thread.sleep
我尝试在 vb 中使用睡眠制作动画洪水填充(扫描线算法)。所以它会显示像素被着色的顺序。它会工作一点点,但随后会 return object is currently used elshere
这是我的代码
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
我是这样称呼它的
Dim thr As New Threading.Thread(Sub() AnimatedRFRecursive(point, C, Color))
thr.Start()
请告诉我我哪里做错了,或者如果你有任何其他有效的方法也可以。谢谢
您有多个线程需要访问同一个对象 (BMP)。这将要求您同步对 BMP 对象的访问。
请注意,您的原始代码有两个幻数(500 和 349),我假设它们对应于位图的宽度和高度。如果此假设不正确,请更改以下代码中变量的用法。
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
我尝试在 vb 中使用睡眠制作动画洪水填充(扫描线算法)。所以它会显示像素被着色的顺序。它会工作一点点,但随后会 return object is currently used elshere
这是我的代码
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
我是这样称呼它的
Dim thr As New Threading.Thread(Sub() AnimatedRFRecursive(point, C, Color))
thr.Start()
请告诉我我哪里做错了,或者如果你有任何其他有效的方法也可以。谢谢
您有多个线程需要访问同一个对象 (BMP)。这将要求您同步对 BMP 对象的访问。
请注意,您的原始代码有两个幻数(500 和 349),我假设它们对应于位图的宽度和高度。如果此假设不正确,请更改以下代码中变量的用法。
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