A short semi fast flood fill.

If anyone has trouble with this, please post. I'm about to run it on 10+ million shapes. There always seem to be a few unique situations where something doesn't work.

Public Sub Fill(ByVal bmp As Bitmap, ByVal pos As Point, ByVal color As Color)
        If bmp Is Nothing OrElse pos.X < 0 OrElse pos.Y < 0 OrElse pos.X >= bmp.Width OrElse pos.Y > bmp.Height Then Exit Sub

        Dim bmd As BitmapData = bmp.LockBits(New Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat)
        Dim stride As Integer = bmd.Stride
        Dim Bpp As Integer = stride / bmp.Width
        Dim overStride As Integer = stride - bmp.Width * Bpp
        Dim Stack As New Stack
        Dim ptr As IntPtr = bmd.Scan0
        Dim CurrentOffset, Offset, CheckedOffset As Integer
        Dim OffsetChecked((stride) * bmp.Height - 1) As Boolean
        Dim _Bytes((stride) * bmp.Height - 1) As Byte
        Dim _OrgColor(2) As Byte
        Dim _nwColor(2) As Byte
        Dim x() As Integer = {1, 0, -1, 0}
        Dim y() As Integer = {0, 1, 0, -1}
        Dim farOffset As Integer
        Dim farX As Integer

        Marshal.Copy(ptr, _Bytes, 0, _Bytes.Length)

        CurrentOffset = pos.Y * stride + pos.X * Bpp
        Stack.Push(CurrentOffset)

        'Set the original color and the color passed in
        Array.Copy(_Bytes, CurrentOffset, _OrgColor, 0, 3)
        _nwColor(0) = color.B
        _nwColor(1) = color.G
        _nwColor(2) = color.R

        Do While Stack.Count > 0

            CurrentOffset = Stack.Pop
            Array.Copy(_nwColor, 0, _Bytes, CurrentOffset, 3)


            For i = 0 To 3
                'check left and right side bounds
                If ((CurrentOffset) Mod stride = 0 And x(i) = -1) OrElse ((CurrentOffset + Bpp + overStride) Mod stride = 0 And x(i) = 1) Then Continue For

                Offset = CurrentOffset + (y(i) * (stride) + x(i) * Bpp)
                CheckedOffset = Offset / Bpp

                'check top and bottom bounds
                If Offset < 0 OrElse Offset > _Bytes.Length - Bpp OrElse OffsetChecked(CheckedOffset) = True Then Continue For

                If _Bytes(Offset) = _OrgColor(0) AndAlso _Bytes(Offset + 1) = _OrgColor(1) AndAlso _Bytes(Offset + 2) = _OrgColor(2) Then
                    OffsetChecked(CheckedOffset) = True
                    Stack.Push(Offset)
                    If ((Offset / stride) Mod 1) * stride / Bpp > farX Then
                        farOffset = Offset
                        farX = ((Offset / stride) Mod 1) * stride / Bpp
                    End If
                End If
            Next
        Loop

        Marshal.Copy(_Bytes, 0, ptr, _Bytes.Length)
        bmp.UnlockBits(bmd)

        ptr = IntPtr.Zero
        _Bytes = Nothing
        OffsetChecked = Nothing

    End Sub

Edited 3 Years Ago by mike_2000_17: Fixed formatting

Unhnd_Exception
Deleted Member

this if statement can be deleted. It was for something else.
If ((Offset / stride) Mod 1) * stride / Bpp > farX Then
farOffset = Offset
farX = ((Offset / stride) Mod 1) * stride / Bpp
End If

Call it in a picturebox event

private sub Picturebox1_MouseDown(byval sender as object, byval e as mouseeventargs)

fill(picturebox1.image,e.location,color.red)
picturebox1.refresh

end sub

This question has already been answered. Start a new discussion instead.