Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 802
  • Last Modified:

Gridlines beneath an eraseable drawing picturebox

Hi,
I am trying to create a simple drawing application that allows a user to draw onto a picture box, use an eraser tool if necessary and then save the image to a file.
This is straightforward enough however I have been asked to show gridlines beneath the image. These show ok however when a user uses my eraser, they also cause the gridlines to be erased as well.
All my eraser routine is doing is drawing a white line over the picture box thus erasing any black pixels but also causing these new white pixels to be shown over the grid bitmap behind.

I think ... that I need a way of setting the pixels drawn with the eraser back to transparent if this is possible or would appreciate any other ideas people have. I've attacehed the basic code below:
Dim _guideLines As Boolean
    Dim BMP As Bitmap
    Dim BMPGL As Bitmap
    Dim GR As Graphics
    Dim GRGL As Graphics
    Dim DISP As Bitmap
    Dim DispGR As Graphics
 
    Private m_drawing As Boolean
    Private m_X As Integer
    Private m_Y As Integer
 
 
    Private cc As Pen = Pens.Black
 
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        BMP = New Bitmap(piccanvas.Width, piccanvas.Height)
        BMPGL = New Bitmap(piccanvas.Width, piccanvas.Height)
        DISP = New Bitmap(piccanvas.Width, piccanvas.Height)
        GR = Graphics.FromImage(BMP)
        GRGL = Graphics.FromImage(BMPGL)
 
        DispGR = Graphics.FromImage(DISP)
        DispGR.Clear(Color.White)
 
        DrawGridLines()
 
    End Sub
 
    Private Sub DrawGridLines()
        Dim x As Integer
        Dim y As Integer
 
        For x = 1 To 10
            For y = 1 To 10
                GRGL.DrawLine(Pens.Blue, (x * 50), 0, (x * 50), piccanvas.Height)
                GRGL.DrawLine(Pens.Blue, 0, y * 50, piccanvas.Width, y * 50)
            Next
        Next
    End Sub
 
    Private Sub CheckBox2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox2.Click
        If CheckBox2.checked Then
            cc = Pens.White
        Else
            cc = Pens.Black
        End If
    End Sub
 
 
    Private Sub CheckBox1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox1.Click
        If _guideLines Then
            _guideLines = False
            CheckBox1.Checked = False
 
            DispGR.Clear(Color.White)
            DispGR.DrawImage(BMP, New Point(0, 0))
            piccanvas.Image = DISP
 
        Else
            _guideLines = True
            CheckBox1.Checked = True
 
            DispGR.Clear(Color.White)
            DispGR.DrawImage(BMPGL, New Point(0, 0))
            DispGR.DrawImage(BMP, New Point(0, 0))
            piccanvas.Image = DISP
        End If
    End Sub
 
    Private Sub PictureBox1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles piccanvas.MouseDown
        m_drawing = True
        m_X = e.X
        m_Y = e.Y
    End Sub
 
    Private Sub PictureBox1_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles piccanvas.MouseMove
        If Not m_drawing Then Exit Sub
        GR.DrawLine(cc, m_X, m_Y, e.X, e.Y)
        m_X = e.X
        m_Y = e.Y
 
        DispGR.DrawImage(BMP, New Point(0, 0))
        piccanvas.Image = DISP
    End Sub
 
    Private Sub PictureBox1_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles piccanvas.MouseUp
        m_drawing = False
    End Sub

Open in new window

0
km176351
Asked:
km176351
  • 5
  • 4
1 Solution
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Comment out your DrawGridLines() call:

        ' DrawGridLines()

...and try drawing the Gridlines in the Paint() Event intead:
    Private Sub piccanvas_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles piccanvas.Paint
        For x As Integer = 1 To 10
            For y As Integer = 1 To 10
                e.Graphics.DrawLine(Pens.Blue, (x * 50), 0, (x * 50), piccanvas.Height)
                e.Graphics.DrawLine(Pens.Blue, 0, y * 50, piccanvas.Width, y * 50)
            Next
        Next
    End Sub

Open in new window

0
 
km176351Author Commented:
Close... very close

But ideally the grid needs to be behind the image so that if you drew a line directly over a grid line, you would see the drawn line rather than the grid line
0
 
km176351Author Commented:
Also,
Because the image will be saved to file, I will need the saved image to look correct too:

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        DISP.Save("c:\Test.jpg", System.Drawing.Imaging.ImageFormat.Jpeg)
    End Sub
0
Fill in the form and get your FREE NFR key NOW!

Veeam is happy to provide a FREE NFR server license to certified engineers, trainers, and bloggers.  It allows for the non‑production use of Veeam Agent for Microsoft Windows. This license is valid for five workstations and two servers.

 
Mike TomlinsonMiddle School Assistant TeacherCommented:
You want the gridlines to be part of the finished image?
0
 
km176351Author Commented:
Hi sorry for not being clearer but ideally yes.
The effect I am trying to achieve is that the user is confronted with a canvas with grid lines displayed on it. When the user draws on the canvas, the drawn features appear on top of the grid lines. When the user uses the eraser, only the drawn features get erased and not the gridlines.
This picture as a whole (including the gridlines) should then be saveable to file.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Ok...no problem.  I'm pretty sure I have a simple workable solution for you.  What version VB.Net are you running though?
0
 
km176351Author Commented:
Hi,
I'm using 2005 although I can quite easily switch to 2008 if necessary
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Try this out with a New Project.  It has a PictureBox (piccanvas), two RadioButtons, and a Button.
Imports System.Drawing.Drawing2D
Public Class Form1
 
    Private Class Squiggle
        Public Shared Width As Integer = 8
        Public GP As New GraphicsPath
        Public Drawn As Boolean = True
    End Class
 
    Private lastX, lastY As Integer
    Private S As Squiggle
    Private Squiggles As New List(Of Squiggle)
 
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim bmp As New Bitmap(piccanvas.ClientRectangle.Width, piccanvas.ClientRectangle.Height)
        Dim G As Graphics = Graphics.FromImage(bmp)
        For x As Integer = 50 To bmp.Width Step 50
            For y As Integer = 50 To bmp.Height Step 50
                G.DrawLine(Pens.Blue, x, 0, x, bmp.Height)
                G.DrawLine(Pens.Blue, 0, y, bmp.Width, y)
            Next
        Next
        G.Dispose()
        piccanvas.Image = bmp
    End Sub
 
    Private Sub piccanvas_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles piccanvas.MouseDown
        If e.Button = Windows.Forms.MouseButtons.Left Then
            lastX = e.X
            lastY = e.Y
            S = New Squiggle
            S.Drawn = RadioButton1.Checked
        End If
    End Sub
 
    Private Sub piccanvas_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles piccanvas.MouseMove
        If e.Button = Windows.Forms.MouseButtons.Left Then
            S.GP.AddLine(lastX, lastY, e.X, e.Y)
            lastX = e.X
            lastY = e.Y
            piccanvas.Refresh()
        End If
    End Sub
 
    Private Sub piccanvas_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles piccanvas.MouseUp
        If e.Button = Windows.Forms.MouseButtons.Left Then
            Dim p As New Pen(Color.Black, Squiggle.Width)
            S.GP.Widen(p)
            p.Dispose()
            Squiggles.Add(S)
            S = Nothing
            piccanvas.Refresh()
        End If
    End Sub
 
    Private Sub piccanvas_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles piccanvas.Paint
        Dim R As New Region
        R.MakeEmpty()
 
        For Each S As Squiggle In Squiggles
            If S.Drawn Then
                R.Union(S.GP)
            Else
                R.Exclude(S.GP)
            End If
        Next
 
        If Not IsNothing(S) Then
            Dim tempGP As GraphicsPath = S.GP.Clone
            Dim p As New Pen(Color.Black, Squiggle.Width)
            tempGP.Widen(p)
            p.Dispose()
            If S.Drawn Then
                R.Union(tempGP)
            Else
                R.Exclude(tempGP)
            End If
        End If
 
        e.Graphics.SetClip(R, CombineMode.Replace)
        e.Graphics.FillRectangle(Brushes.Black, piccanvas.ClientRectangle)
    End Sub
 
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim bmp As New Bitmap(piccanvas.ClientRectangle.Width, piccanvas.ClientRectangle.Height)
        piccanvas.DrawToBitmap(bmp, piccanvas.ClientRectangle)
        bmp.Save(System.IO.Path.Combine(My.Computer.FileSystem.SpecialDirectories.MyDocuments, "drawing.jpg"), System.Drawing.Imaging.ImageFormat.Jpeg)
    End Sub
 
End Class

Open in new window

Squiggle.jpg
0
 
km176351Author Commented:
That is exactly the functionality I was trying to achieve - Many thanks!
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 5
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now