Iterative implementation using a neighbor stack.
For each colored pixel, the four neighbors are explored and those that need to be colored are placed on a stack.
The pixels in the stack are colored, and the computation stops when the stack is empty.
For better accuracy, make sure your image is well cleaned.
en.wikipedia.org
[CODE lang="b4x" title="B4X"]Sub Globals
Private bmp As B4XBitmap
Private bc As BitmapCreator
Private selectedColor As Int = xui.Color_Transparent
Private cvs As B4XCanvas
Private pnlCanvas As B4XView
Private Byteconv As ByteConverter
End Sub
Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("Layout")
bmp = LoadBitmap(File.DirAssets, "image.bmp") ' Loads the bitmap image
bc.Initialize(bmp.Width, bmp.Height)
bc.CopyPixelsFromBitmap(bmp)
Dim DestRect As B4XRect
DestRect.Initialize(0, 0, bmp.Width, bmp.Height)
cvs.Initialize(pnlCanvas)
cvs.DrawBitmap(bmp,DestRect) ' Draw image on canvas
cvs.Invalidate
End Sub
Sub pnlCanvas_Touch (Action As Int, X As Float, Y As Float)
If Action = Activity.ACTION_UP Then ' Click detection
FloodFill(X, Y, selectedColor)
bmp = bc.Bitmap
Dim DestRect As B4XRect
DestRect.Initialize(0, 0, bmp.Width, bmp.Height)
cvs.DrawBitmap(bmp,DestRect) ' Updates the drawing
cvs.Invalidate
End If
End Sub
' Diffusion Filling Algorithm
Sub FloodFill(x As Int, y As Int, color As Int)
Dim queue As List
queue.Initialize
queue.Add(Array As Int(x, y))
Dim targetColor As Int = bc.GetColor(x, y)
If targetColor = color Then Return
Do While queue.Size > 0
Dim point() As Int = queue.Get(0)
queue.RemoveAt(0)
Dim px As Int = point(0)
Dim py As Int = point(1)
If px >= 0 And px < bc.mWidth And py >= 0 And py < bc.mHeight Then
If bc.GetColor(px, py) = targetColor Then
bc.SetColor(px, py, color)
queue.Add(Array As Int(px + 1, py))
queue.Add(Array As Int(px - 1, py))
queue.Add(Array As Int(px, py + 1))
queue.Add(Array As Int(px, py - 1))
End If
End If
Loop
End Sub
Private Sub Color_Click
Dim l As Label = Sender
selectedColor = HexToColor(l.Tag) ' Color selected
End Sub
Private Sub HexToColor(Hex As String) As Int
If Hex.StartsWith("#") Then
Hex = Hex.SubString(1)
Else If Hex.StartsWith("0x") Then
Hex = Hex.SubString(2)
End If
Dim ints() As Int = Byteconv.IntsFromBytes(Byteconv.HexToBytes(Hex))
Return ints(0)
End Sub[/CODE]