Okay, so as a project for one of my classes I need to make a basic drawing program in VB that can do three things:

  • "Draw" with a brush of some sort
  • Clear the screen
  • Perform a flood-fill (paintbucket action)

I decided to do the first two tasks first, and got them to work, but the third task completely eludes me. Every way I try seems to pile on exceptions, and every flood-fill algorithm I find seems to require a bitmap, rather than a Graphics() object. Is there any way to accomplish a flood-fill using a Graphics object, or must I restart the project using a bitmap?


Source code for reference:

Public Class Form1
    Public gfx As Graphics
    Public mainBrush As New SolidBrush(Color.Black)

    'creates a graphics surface when the program starts, disposes it when form closes.
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        gfx = pnlDraw.CreateGraphics()
        dlgColor.Color = Color.Black
    End Sub

    Private Sub Form1_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
        gfx.Dispose()
    End Sub

    '"draws" when the left mosue button is held down and moved, so long as the radiobutton to select draw is checked
    Private Sub pnlDraw_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles pnlDraw.MouseMove
        If e.Button <> Windows.Forms.MouseButtons.Left Then Exit Sub

        If radDraw.Checked = True Then
            Dim rect As Rectangle

            With rect
                .X = e.X - (sizeSlider.Value / 2)
                .Y = e.Y - (sizeSlider.Value / 2)
                .Width = sizeSlider.Value
                .Height = sizeSlider.Value
            End With
            gfx.FillEllipse(mainBrush, rect)
        End If

    End Sub

    Private Sub sizeSlider_Scroll(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ScrollEventArgs) Handles sizeSlider.Scroll
        lblSize.Text = sizeSlider.Value
    End Sub


    Private Sub btnClear_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClear.Click
        gfx.Clear(Color.White)
    End Sub

    'changes "brush" color
    Private Sub colorSelect_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles colorSelect.DoubleClick
        If dlgColor.ShowDialog() = DialogResult.OK Then
            colorSelect.BackColor = dlgColor.Color
            mainBrush.Color = dlgColor.Color
        End If
    End Sub
End Class

Your going to need to use a Bitmap.

You should use a bitmap anyways. With what you have above if you minimize the screen and maximize the screen, all drawing will be erased.

You can use gx = Graphics.FromImage(whateveryourbitmapis)

Check out Bob Powells site for creating a flood fill

http://www.bobpowell.net/floodfill.aspx

It gave me a starting point.

If you run into any problems let me know.

Okay, so I finally got around to re-writing this...cept I can't get the "line drawing" thing done now, as the method I used before doesn't work if I implement a bitmap-based system...kinda at a loss for the moment.

Here's the code I have written at the moment, any help would be appreciated.:

Public Class Form1
    Public mainBrush As New SolidBrush(Color.Black)
    'Private canvasWidth As Integer = pnlCanvas.Width
    'Private canvasHeight As Integer = pnlCanvas.Height
    Public canvas As New Bitmap(600, 350)
    Public isDrawSel, isFillSel As Boolean
    Public brushSize As Integer = 100

    Private Sub fileClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles fileClose.Click
        Me.Close()
    End Sub

    Private Sub draw_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles draw.Click
        draw.Text = "*Draw"
        bucketFill.Text = "Bucket Fill"
    End Sub

    Private Sub bucketFill_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bucketFill.Click
        draw.Text = "Draw"
        bucketFill.Text = "*Bucket Fill"
    End Sub


    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        pnlCanvas.BackgroundImage = canvas
    End Sub

    
    Private Sub pnlCanvas_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles pnlCanvas.Paint

    End Sub

    Private Sub pnlCanvas_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles pnlCanvas.MouseMove
        If e.Button <> Windows.Forms.MouseButtons.Left Then Exit Sub

        Dim gfx As Graphics = Graphics.FromImage(canvas)

        Dim rect As Rectangle

        With rect
            .X = e.X - (brushSize / 2)
            .Y = e.Y - (brushSize / 2)
            .Width = brushSize
            .Height = brushSize
        End With
        gfx.FillEllipse(mainBrush, rect)


        Dim bmpTemp As New Bitmap(600, 350, gfx)
        canvas = bmpTemp
        pnlCanvas.BackgroundImage = canvas

        gfx.Dispose()
    End Sub
End Class
This article has been dead for over six months. Start a new discussion instead.