Android Question Diffusion Filling Algorithm

zed

Active Member
Licensed User
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.


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
 

Attachments

  • Screenshot_FloodFill.png
    Screenshot_FloodFill.png
    303.1 KB · Views: 48
  • FloodFill.zip
    10 KB · Views: 34
Top