Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
flood fill ?
#16
I added the EnableBlend% parameter to disable the blend check and it's twice as fast. 
@Petr's fill (paint2) was fastest after native paint, though I still don't understand what he's doing.
Here's a test of all of them:

Code: (Select All)
' Paint vs Fill speed comparison by Steve, v2 by madscijr
' https://qb64phoenix.com/forum/showthread.php?tid=3631&pid=33725#pid33725

Screen _NewImage(800, 800, 32)
Circle (400, 400), 400, _RGB32(255, 255, 255) 'white circle
TestNum% = 0
TextCols% = (_Width / _FontWidth) - 1

NumTests% = 5

TestNum% = TestNum% + 1
t0# = Timer

For i = 1 To 100
    Color _RGB32(255, 255, 255), _RGB32(0, 0, 0)
    Locate 1, 1: Print "Test " + _ToStr$(TestNum%) + " of " + _ToStr$(NumTests%) + " (Paint)                   "
    Locate 2, 1: Print "Fill " + Right$("   " + _ToStr$(i), 3) + " of 100  "
    Paint (400, 400), _RGB32(Rnd * 256, Rnd * 256, Rnd * 256), _RGB32(255, 255, 255)
Next i

TestNum% = TestNum% + 1
t1# = Timer

For i = 1 To 100
    Color _RGB32(255, 255, 255), _RGB32(0, 0, 0)
    Locate 1, 1: Print "Test " + _ToStr$(TestNum%) + " of " + _ToStr$(NumTests%) + " (Fill EnableBlend%=_FALSE)"
    Locate 2, 1: Print "Fill " + Right$("   " + _ToStr$(i), 3) + " of 100  "
    Fill 400, 400, _RGB32(Rnd * 256, Rnd * 256, Rnd * 256), _FALSE
Next i

TestNum% = TestNum% + 1
t2# = Timer

For i = 1 To 100
    Color _RGB32(255, 255, 255), _RGB32(0, 0, 0)
    Locate 1, 1: Print "Test " + _ToStr$(TestNum%) + " of " + _ToStr$(NumTests%) + " (Fill EnableBlend%=_TRUE) "
    Locate 2, 1: Print "Fill " + Right$("   " + _ToStr$(i), 3) + " of 100  "
    Fill 400, 400, _RGB32(Rnd * 256, Rnd * 256, Rnd * 256), _TRUE
Next i

TestNum% = TestNum% + 1
t3# = Timer

For i = 1 To 100
    Color _RGB32(255, 255, 255), _RGB32(0, 0, 0)
    Locate 1, 1: Print "Test " + _ToStr$(TestNum%) + " of " + _ToStr$(NumTests%) + " (Paint2)                  "
    Locate 2, 1: Print "Fill " + Right$("   " + _ToStr$(i), 3) + " of 100  "
    Paint2 400, 400, _RGB32(Rnd * 256, Rnd * 256, Rnd * 256)
Next i

TestNum% = TestNum% + 1
t4# = Timer

' only test 1x, or else we'll be here all day!
For i = 1 To 1
    Color _RGB32(255, 255, 255), _RGB32(0, 0, 0)
    Locate 1, 1: Print "Test " + _ToStr$(TestNum%) + " of " + _ToStr$(NumTests%) + " (Paint3)                  "
    Locate 2, 1: Print "Fill " + Right$("   " + _ToStr$(i), 3) + " of 1    "
    paint3 400, 400, _RGB32(Rnd * 256, Rnd * 256, Rnd * 256)
Next i

t5# = Timer

Locate 1, 1: Print Left$("Test complete" + String$(TextCols%, " "), TextCols%)
Locate 2, 1: Print Left$("Results for 100 fills:" + String$(TextCols%, " "), TextCols%)
Color _RGB32(255, 255, 255), _RGB32(0, 0, 255)
Locate 3, 2: Print Using "###.### seconds Paint                   "; t1# - t0#
Locate 4, 2: Print Using "###.### seconds Fill EnableBlend%=_FALSE "; t2# - t1#
Locate 5, 2: Print Using "###.### seconds Fill EnableBlend%=_TRUE  "; t3# - t2#
Locate 6, 2: Print Using "###.### seconds Paint2                  "; t4# - t3#
Locate 7, 2: Print Using "###.### seconds Paint3                  "; (t5# - t4#) * 100

' ################################################################################################################################################################
' # BEGIN BPlus's fill code
' ################################################################################################################################################################

' /////////////////////////////////////////////////////////////////////////////
' From: bplus, Mini-Mod
' 4/23/2025 8:53 PM

' I have a different kind of paint, Paint3 that fills the color
' it lands on to do the painting, any other color stops the
' paint like a border

' madscijr added check for Esc key to cancel

Sub paint3 (x0, y0, MyFill As _Unsigned Long) ' needs GetMax, GetMin functions
    Dim fillColor As _Unsigned Long, W, H, parentF, tick, ystart, ystop, xstart, xstop, x, y

    fillColor = Point(x0, y0)
    'PRINT fillColor
    W = _Width - 1: H = _Height - 1

    Dim temp(W, H)
    temp(x0, y0) = 1: parentF = 1
    PSet (x0, y0), MyFill

    Dim k&: k& = 0 ' madscijr

    While parentF = 1
        parentF = 0: tick = tick + 1
        ystart = GetMax(y0 - tick, 0): ystop = GetMin(y0 + tick, H)
        y = ystart
        While y <= ystop
            xstart = GetMax(x0 - tick, 0): xstop = GetMin(x0 + tick, W)
            x = xstart
            While x <= xstop
                If Point(x, y) = fillColor And temp(x, y) = 0 Then
                    If temp(GetMax(0, x - 1), y) Then
                        temp(x, y) = 1: parentF = 1: PSet (x, y), MyFill
                    ElseIf temp(GetMin(x + 1, W), y) Then
                        temp(x, y) = 1: parentF = 1: PSet (x, y), MyFill
                    ElseIf temp(x, GetMax(y - 1, 0)) Then
                        temp(x, y) = 1: parentF = 1: PSet (x, y), MyFill
                    ElseIf temp(x, GetMin(y + 1, H)) Then
                        temp(x, y) = 1: parentF = 1: PSet (x, y), MyFill
                    End If
                End If
                x = x + 1

                k& = _KeyHit: If k& = 27 Then Exit While ' madscijr
            Wend
            If k& = 27 Then Exit While ' madscijr

            y = y + 1

            k& = _KeyHit: If k& = 27 Then Exit While ' madscijr
        Wend
        If k& = 27 Then Exit While ' madscijr

        k& = _KeyHit: If k& = 27 Then Exit While ' madscijr
    Wend
End Sub ' paint3

' /////////////////////////////////////////////////////////////////////////////

Function GetMin (n1, n2)
    If n1 > n2 Then GetMin = n2 Else GetMin = n1
End Function

' /////////////////////////////////////////////////////////////////////////////

Function GetMax (n1, n2)
    If n1 < n2 Then GetMax = n2 Else GetMax = n1
End Function

' ################################################################################################################################################################
' # END BPlus's fill code
' ################################################################################################################################################################

' ################################################################################################################################################################
' # BEGIN Steve's fill code
' ################################################################################################################################################################

' /////////////////////////////////////////////////////////////////////////////
' SMcNeill, Super Moderator
' 4/23/2025 8:55 PM

Sub FillSteve
    $Color:32
    Screen _NewImage(1280, 720, 32)
    _ScreenMove 0, 0

    Circle (640, 360), 350, Red
    Circle (800, 500), 100, Blue
    Paint (800, 500), Blue, Blue

    Locate 1, 1
    Color _RGB32(255, 255, 255), _RGB32(0, 0, 0)
    Print "Press any key to fill"
    Sleep ' so we can see that the blue circle is inside the red one.

    Fill 640, 360, Red, _FALSE 'fill all transparent pixels red

    Locate 1, 1
    Color _RGB32(255, 255, 255), _RGB32(0, 0, 0)
    Print "Press any key to exit"
    Sleep
End Sub ' FillSteve

' /////////////////////////////////////////////////////////////////////////////

Sub Fill (x, y, Kolor As _Unsigned Long, EnableBlend%)
    Dim As _Unsigned Long OC, BC
    OC = Point(x, y) 'original color

    If EnableBlend% = _TRUE Then
        ' blend is enabled
        If _Alpha32(Kolor) <> 255 Or _Alpha32(OC) <> 255 Then ' we're going to blend
            PSet (x, y), Kolor
            BC = Point(x, y) ' blended color
        End If
        BlendFiller x, y, Kolor, OC, BC
    Else
        Filler x, y, Kolor, OC
    End If
End Sub ' Fill

' /////////////////////////////////////////////////////////////////////////////
' Paintbucket fill (opaque)

Sub Filler (x, y, Kolor As _Unsigned Long, OC As _Unsigned Long)
    Dim l, r, i
    If Kolor = OC Then Exit Sub
    l = x: r = x 'find left/right to fill
    Do Until l = 0
        If Point(l - 1, y) = OC Then l = l - 1 Else Exit Do
    Loop 'find the left boundry
    Do Until r = _Width - 1
        If Point(r + 1, y) = OC Then r = r + 1 Else Exit Do
    Loop 'find the right boundry
    Line (l, y)-(r, y), Kolor, BF
    For i = l To r
        If Point(i, y + 1) = OC Then Filler i, y + 1, Kolor, OC
    Next
    For i = l To r
        If Point(i, y - 1) = OC Then Filler i, y - 1, Kolor, OC
    Next
End Sub ' Filler

' /////////////////////////////////////////////////////////////////////////////
' Paintbucket fill with blending colors w/alpha < 255

Sub BlendFiller (x, y, Kolor As _Unsigned Long, OC As _Unsigned Long, BC As _Unsigned Long)
    Dim l, r, i
    If Kolor = OC Or Kolor = BC Then Exit Sub
    l = x: r = x 'find left/right to fill
    Do Until l = 0
        If Point(l - 1, y) = BC Then Exit Do
        If Point(l - 1, y) = OC Then l = l - 1 Else Exit Do
    Loop 'find the left boundry
    Do Until r = _Width - 1
        If Point(r + 1, y) = BC Then Exit Do
        If Point(r + 1, y) = OC Then r = r + 1 Else Exit Do
    Loop 'find the right boundry
    Line (l, y)-(r, y), Kolor, BF
    For i = l To r
        If Point(i, y + 1) = BC Then _Continue
        If Point(i, y + 1) = OC Then BlendFiller i, y + 1, Kolor, OC, BC
    Next
    For i = l To r
        If Point(i, y - 1) = BC Then _Continue
        If Point(i, y - 1) = OC Or Point(l - 1, y) = BC Then BlendFiller i, y - 1, Kolor, OC, BC
    Next
End Sub ' BlendFiller

' ################################################################################################################################################################
' # END Steve's fill code
' ################################################################################################################################################################

' ################################################################################################################################################################
' # BEGIN Petr's fill code
' ################################################################################################################################################################

' /////////////////////////////////////////////////////////////////////////////
' Petr, Mini-Mod
' 4/24/2025 9:42 AM
' https://qb64phoenix.com/forum/showthread.php?tid=1507

Sub Paint2 (x, y, c~&)
    Dim W
    Dim H
    Dim Virtual As Long
    Dim position&
    Dim Clr2~&
    Dim D&
    Dim CLR~&

    W = _Width: H = _Height
    Virtual = _NewImage(W, H, 32)

    Dim m As _MEM, n As _MEM, Bck As _Unsigned Long

    m = _MemImage(_Source)
    n = _MemImage(Virtual)

    'create mask (2 color image)
    position& = (y * W + x) * 4

    _MemGet m, m.OFFSET + position&, Bck

    Clr2~& = _RGB32(_Red32(Bck) - 1, _Green32(Bck) - 1, _Blue32(Bck) - 1, _Alpha32(Bck) - 1)

    D& = 0

    Do Until D& = n.SIZE
        CLR~& = _MemGet(m, m.OFFSET + D&, _Unsigned Long)
        If CLR~& = Bck~& Then _MemPut n, n.OFFSET + D&, CLR~& Else _MemPut n, n.OFFSET + D&, Clr2~&
        D& = D& + 4
    Loop

    D& = _Dest

    _Dest Virtual
    Paint (x, y), c~&, Clr2~&
    _Dest D&
    _ClearColor Clr2~&, Virtual
    _PutImage , Virtual, D&

    _MemFree m
    _MemFree n
    _FreeImage Virtual
End Sub ' Paint2
' ################################################################################################################################################################
' # END Petr's fill code
' ################################################################################################################################################################
Reply


Messages In This Thread
flood fill ? - by madscijr - 04-23-2025, 07:38 PM
RE: flood fill ? - by bplus - 04-23-2025, 11:06 PM
RE: flood fill ? - by madscijr - 04-24-2025, 12:08 AM
RE: flood fill ? - by bplus - 04-24-2025, 12:20 AM
RE: flood fill ? - by SMcNeill - 04-24-2025, 12:44 AM
RE: flood fill ? - by SMcNeill - 04-24-2025, 12:54 AM
RE: flood fill ? - by madscijr - 04-24-2025, 03:23 AM
RE: flood fill ? - by Petr - 04-24-2025, 01:28 PM
RE: flood fill ? - by madscijr - 04-24-2025, 11:50 PM
RE: flood fill ? - by SMcNeill - 04-25-2025, 12:58 AM
RE: flood fill ? - by SMcNeill - 04-25-2025, 01:52 AM
RE: flood fill ? - by madscijr - 04-25-2025, 05:51 AM
RE: flood fill ? - by madscijr - 04-25-2025, 02:27 AM
RE: flood fill ? - by SMcNeill - 04-25-2025, 11:36 AM
RE: flood fill ? - by madscijr - 04-25-2025, 01:11 PM
RE: flood fill ? - by madscijr - 04-25-2025, 06:49 PM
RE: flood fill ? - by madscijr - 04-25-2025, 07:36 PM
RE: flood fill ? - by TempodiBasic - 04-27-2025, 07:15 PM
RE: flood fill ? - by madscijr - 04-27-2025, 08:36 PM
RE: flood fill ? - by CMR - 04-29-2025, 02:56 AM
RE: flood fill ? - by SMcNeill - 04-29-2025, 02:59 AM
RE: flood fill ? - by CMR - 05-01-2025, 05:59 PM
RE: flood fill ? - by SMcNeill - 05-01-2025, 07:20 PM
RE: flood fill ? - by CMR - 05-03-2025, 02:28 AM
RE: flood fill ? - by Petr - 05-01-2025, 06:35 PM

Possibly Related Threads…
Thread Author Replies Views Last Post
  Simple Brick Pattern Fill Question NakedApe 3 918 12-01-2023, 09:37 PM
Last Post: NakedApe

Forum Jump:


Users browsing this thread: 1 Guest(s)