Solved

How can I erase a line.

Posted on 2014-11-15
8
265 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 86

Expert Comment

by:Mike Tomlinson
ID: 40444705
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
ID: 40445403
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 86

Expert Comment

by:Mike Tomlinson
ID: 40445900
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:Chris Joyce
ID: 40451775
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
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 40452526
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
ID: 40454539
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 86

Accepted Solution

by:
Mike Tomlinson earned 500 total points
ID: 40455633
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
ID: 40455960
Fantastic, you got there in the end. A great, practical solution. Thanks
Chris
0

Featured Post

Secure Your Active Directory - April 20, 2017

Active Directory plays a critical role in your company’s IT infrastructure and keeping it secure in today’s hacker-infested world is a must.
Microsoft published 300+ pages of guidance, but who has the time, money, and resources to implement? Register now to find an easier way.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article will inform Clients about common and important expectations from the freelancers (Experts) who are looking at your Gig.
Today, the web development industry is booming, and many people consider it to be their vocation. The question you may be asking yourself is – how do I become a web developer?
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…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

733 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