Solved

How can I erase a line.

Posted on 2014-11-15
8
242 Views
Last Modified: 2014-11-20
My form has a background picture on it. Over this is a Picture Box with its BackColour set to "Transparent"
I draw on the picture box as follows :-

Public Class Form1
    Public Line_Width As Integer = 3
    Public myPen As Pen = New Pen(Drawing.Color.Black, Line_Width)

    Private Sub PictureBox1_MouseMove(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseMove
        Static last As New Point
        If e.Button = Windows.Forms.MouseButtons.Left Then
            Me.PictureBox1.CreateGraphics.DrawLine(myPen, last.X, last.Y, e.X, e.Y)
        End If
        last = e.Location
    End Sub

End Class

This works fine, draws black lines all over the PictureBox. Now I want to erase some of the lines I have just drawn (some, not all). I have a button on the form, its function is to change the pen colour to "Transparent"

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        myPen = New Pen(Drawing.Color.Transparent, 10)
    End Sub

The idea is that drawing a "Transparent" line over an existing "Black" line should erase the Black line. Unfortunatly this does not work.

Any suggestions as to why this does not work, and any ideas as to how I can use the mouse to selectivly erase the black lines?
0
Comment
Question by:Chris Joyce
  • 4
  • 4
8 Comments
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
First of all, you're drawing on a temporary surface with CreateGraphics().  Draw on your PictureBox, then minimize and restore the form and see what happens.

To make your lines persistent you'd have to store the information about the lines at class level, then redraw them each time in the Paint() event of your PictureBox:
Imports System.Drawing.Drawing2D
Public Class Form1

    Private lastPoint As Point
    Private Line_Width As Integer = 3
    Private currentGP As GraphicsPath
    Private Paths As New List(Of GraphicsPath)

    Private Sub PictureBox1_MouseDown(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseDown
        If e.Button = Windows.Forms.MouseButtons.Left Then
            lastPoint = e.Location
            currentGP = New GraphicsPath
            Paths.Add(currentGP)
        End If
    End Sub

    Private Sub PictureBox1_MouseMove(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseMove
        If e.Button = Windows.Forms.MouseButtons.Left Then
            currentGP.AddLine(lastPoint, e.Location)
            lastPoint = e.Location
            PictureBox1.Refresh()
        End If
    End Sub

    Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
        Using myPen As New Pen(Drawing.Color.Black, Line_Width)
            For Each GP As GraphicsPath In Paths
                e.Graphics.DrawPath(myPen, GP)
            Next
        End Using
    End Sub

End Class

Open in new window


Erasing lines is more problematic, and may require a completely different approach to the problem...
0
 

Author Comment

by:Chris Joyce
Comment Utility
I think you have missed the point of my question.
The part of the program to draw lines works perfectly thank you. I do not want to save the lines I have drawn, they are temporary by intent.
I only included details of how the lines were drawn in my question so that you would know how the lines I need to erase were made in the first place.
My question is how can I erase some of the lines I have just dawn. To erase them all is simple "PictureBox1.Refresh" does the job fine.
I thought that drawing over them with the pens colour set to "Transparent" or "Empty" would effectively erase any existing line at that location. It does not.
In fact I have as yet to find any use for the "Transparent" or "Empty" colour option at all.
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
That's kinda of my point as well...  

As I said, you're drawing on a temporary Graphics surface, and basically there isn't any way to erase portions of the lines you've drawn with the approach you're using.  To erase part of them you'd have to store the state of the lines, toggle portions of them "off" somehow, and then redraw them again.  There isn't really a way to "erase" anything drawn on the screen.  The controls draw themselves as they normally do, and you are drawing on top of what they painted (which is why everything disappears when you refresh the picturebox).  In short, you somehow need to use a persistent drawing paradigm, whether that be through storing the information about the lines as I have shown (or something along those lines), or "flattening" the lines to a per pixel state in a Bitmap and drawing that, or a completely different approach.
0
 

Author Comment

by:Chris Joyce
Comment Utility
If that really is the case, what is the point of a pen colour of “Transparent” or “Empty”. The Intellesense tool tip even informs that Empty “Represents a colour that is Null”. I have tried drawing a line using either of these pen colours on a picture box with an opaque back ground, they appear to have absolutely no effect at all. Do they really only equate to “Pen.Off “ in the wonderful world of Microsoft speak?
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
I believe they are principally used in image formats such as .GIF and .PNG where pixels can be "off" or transparent.  Color.Transparent can also be used as the BackColor of some controls so that they take on the color(s) of their parent control.
0
 

Author Comment

by:Chris Joyce
Comment Utility
Thank you for your continuing input on this.
Is not that exactly what I am trying to achieve?  The .jpg  image (an engineering drawing in this case) is displayed as the background image of the form itself (the parent control).
The Picture box has its background colour set to transparent, its size and location are the same as the form. Great I can see the background image of the form through the picture box, but the image is not part of the picture box.
Now my colleagues and I draw lines to annotate / amend the engineering drawing on the picture box control.  Some suggestions are accepted, some rejected, some need to be modified.  I need to be able to erase some of these annotations. That is I need to turn off some of the Pixels of the picture box control so that “they take on the color(s) of their parent control.“ as you put it.
The background image of the form must still be available in some way, as when I “refresh” the picture box, the underlying image is restored to full visibility instantly. This is very different to what happens if I “refresh” the form itself. If you refresh the form you can see it flicker as it is erased and redrawn. It is effectively a selective refreshing of the picture box that I am trying to achieve.
Surely using a Pen.Colour.Transparent setting should achieve exactly that. It should turn of the pixels at the location specified “off” allowing the colour of the parent control to show through.
0
 
LVL 85

Accepted Solution

by:
Mike Tomlinson earned 500 total points
Comment Utility
That is I need to turn off some of the Pixels of the picture box control so that “they take on the color(s) of their parent control.“ as you put it.

True...but immediately before that I stated that this principally applies to working with image formats, not drawing directly on the screen as you are doing.

Case in point, you can create a Bitmap with transparency and display that in your PictureBox instead of drawing directly on the screen.  Now you can draw, and erase, on the Bitmap, and achieve your end goal.  Using a Bitmap falls under the "persistent drawing paradigm" I mentioned earlier as the Bitmap is maintaining which pixels are turned on and off.

In this screenshot I completely blacked out the center of the image and then used the eraser to uncover just the middle.  Just as in your description, the image is actually the background of the Form, and the Bitmap with the colored portion is being displayed in the PictureBox which is on top of the image:
The eraser in action!
Here is the code I used:
Public Class Form1

    Private G As Graphics
    Private BMP As Bitmap
    Private Line_Width As Integer = 10
    Private myPen As Pen = New Pen(Color.Black, Line_Width)
    Private eraser As New Pen(Color.Transparent, Line_Width)
    Private Erasing As Boolean = False

    Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
        BMP = New Bitmap(PictureBox1.Size.Width, PictureBox1.Size.Height)
        BMP.MakeTransparent(Color.Transparent)
        G = Graphics.FromImage(BMP)
        G.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy
        PictureBox1.Image = BMP
        PictureBox1.BackColor = Color.Transparent

        Erasing = False
        Button1.Text = "Draw"
    End Sub

    Private Sub PictureBox1_MouseMove(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseMove
        Static last As New Point
        If e.Button = Windows.Forms.MouseButtons.Left Then
            G.DrawLine(If(Erasing, eraser, myPen), last.X, last.Y, e.X, e.Y)
            PictureBox1.Refresh()
        End If
        last = e.Location
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Erasing = Not Erasing
        Button1.Text = If(Erasing, "Erase", "Draw")
    End Sub

End Class

Open in new window

0
 

Author Closing Comment

by:Chris Joyce
Comment Utility
Fantastic, you got there in the end. A great, practical solution. Thanks
Chris
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

A short article about a problem I had getting the GPS LocationListener working.
If you’re thinking to yourself “That description sounds a lot like two people doing the work that one could accomplish,” you’re not alone.
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now