VB.NET paint application - vb.net

I'm facing two problems in my application:
The Undo Function
The Drawing Part
When i draw on the picturebox , it draws very well, when - let's say I want to undo an action, it undo's it but when I click back on the picturebox it reacts like a redo function ,all the drawings appear back on the image.
the second problem is : i want to be able to edit a picture so i load a image by clicking on a listview item but due to something i'm missing the image it is not show but instead it shows a white background in which i am able to draw.
bellow is the code i am using
Imports Microsoft.VisualBasic.PowerPacks
Public Class Form1
Public drawgraph, g As Graphics
Private redoBuffer As New Stack(Of Image)()
Private undoBuffer As New Stack(Of Image)()
Dim color As Color
Dim UndoStack As New Stack(Of Bitmap)()
Dim xStart, yStart, xEnd, yEnd As Integer
Public Drawbitmap As Bitmap
Dim Drawgraphics As Graphics
Dim myPen As New Pen(color.Black, 4)
Dim myColor As Color = color.Black
Dim myPenWidth As Integer
Dim myBGColor As Color = color.White
Dim Drawing As Boolean
Private Sub drawMyline()
PictureBox4.Image = Drawbitmap
Drawgraphics.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
Drawgraphics.DrawLine(myPen, xStart, yStart, xEnd, yEnd)
End Sub
Private Sub PushUndo(ByVal b As Bitmap)
UndoStack.Push(b)
End Sub
Private Function PopUndo() As Bitmap
If UndoStack.Count = 0 Then
Return Nothing
Exit Function
End If
If UndoStack.Count > 0 Then
Return UndoStack.Pop
End If
End Function
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Drawbitmap = New Bitmap(PictureBox4.Width, PictureBox4.Height)
Drawgraphics = Graphics.FromImage(Drawbitmap)
PictureBox4.Image = Drawbitmap
Drawgraphics.Clear(color.White)
myPenWidth = NumericUpDown1.Value
xStart = -1
yStart = -1
Drawing = False
End Sub
Private Sub PictureBox7_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PictureBox7.Click
Dim bmp As Bitmap
bmp = PopUndo()
If bmp IsNot Nothing Then
PictureBox4.Image = bmp
End If
End Sub
Private Sub PictureBox4_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox4.MouseDown
Drawing = True
PushUndo(PictureBox4.Image.Clone)
End Sub
Private Sub PictureBox4_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox4.MouseUp
Drawing = False
End Sub
Private Sub PictureBox4_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox4.MouseMove
If Drawing Then
xStart = e.X
yStart = e.Y
drawMyline()
End If
xEnd = e.X
yEnd = e.Y
End Sub
End Class
I tried making changes but i can't load the image i want into the picturebox4 and draw on it , it always loads a white background as for the undo function it works until a click again on picturebox4 and all the undone drawings appear back. Can someone help me fix this 2 problems that I have?

Related

Remove Or Delete the Rectangle drawn on the PictureBox

I am currently solving a bug that will remove the created rectangle on the PictureBox. The problem is that when I click an Item on the PictureBox and Resize the windows form, the rectangle does not move on with the item selected. This is the code creating the rectangle:
Private Sub paintRectangle(pictBox As System.Windows.Forms.PictureBox, pic As Image)
If pic Is Nothing Then Exit Sub
pictBox.Image = pic
If m_rect_x = -1 And m_rect_y = -1 Then
Return
End If
Dim graphic As System.Drawing.Graphics
Dim redselpen As System.Drawing.Pen
Dim yNegative As Integer = 3
redselpen = New System.Drawing.Pen(Color.Blue)
redselpen.DashStyle = Drawing2D.DashStyle.DashDot
If pictBox.Image IsNot Nothing Then
graphic = System.Drawing.Graphics.FromImage(pictBox.Image)
graphic.DrawRectangle(redselpen, m_rect_x, m_rect_y - yNegative, SystemConfig.iRectWidth, SystemConfig.iRectHeight + 2)
pictBox.Image = pictBox.Image
End If
End Sub
After Resizing the Form, I want to remove the create a rectangle on the PictureBox.
I tried this solution but the Rectangle is still in the PictureBox.
How to remove all the drawn rectangles on the picture box? (Not on the image)
But it does not work, the rectangle is still in the picturebox.
Here's a simple example showing the Paint() event of a PictureBox being used to draw a rectangle that can be moved and turned on/off:
Public Class Form1
Private yNegative As Integer = 3
Private pt As New Nullable(Of Point)
Private drawRectangle As Boolean = False
Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
If drawRectangle AndAlso pt.HasValue Then
Using redselpen As New System.Drawing.Pen(Color.Blue)
redselpen.DashStyle = Drawing2D.DashStyle.DashDot
e.Graphics.DrawRectangle(redselpen, pt.Value.X, pt.Value.Y - yNegative, SystemConfig.iRectWidth, SystemConfig.iRectHeight + 2)
End Using
End If
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
pt = New Point(25, 25)
drawRectangle = True
PictureBox1.Invalidate()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
drawRectangle = Not drawRectangle ' toggle the rectangle on/off
PictureBox1.Invalidate()
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
pt = New Point(150, 25)
drawRectangle = True
PictureBox1.Invalidate()
End Sub
End Class

How can I able to see the image in my picturebox?

I have used the following code to draw what I want but when I used this code I cannot see the image I set on my picturebox. What should I do to draw on the picture box with an image? Please help me with this.
Public Class Form1
Dim draw As Boolean
Dim DrawColor As Color = Color.Black
Dim DrawSize As Integer = 6
Dim bmp As Bitmap
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
cbxSize.SelectedIndex = 2
bmp = New Bitmap(pbDraw.Width, pbDraw.Height)
pbDraw.Image = bmp
Dim down = False
End Sub
Private Sub PaintBrush(X As Integer, Y As Integer)
Using g As Graphics = Graphics.FromImage(pbDraw.Image)
g.FillRectangle(New SolidBrush(DrawColor), New Rectangle(X, Y, DrawSize, DrawSize))
End Using
pbDraw.Refresh()
End Sub
Drawing event
Private Sub pbtest_MouseDown(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles pbDraw.MouseDown
draw = True
PaintBrush(e.X, e.Y)
End Sub
Private Sub pbtest_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles pbDraw.MouseMove
If draw = True Then
PaintBrush(e.X, e.Y)
End If
End Sub
Private Sub pbtest_MouseUp(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles pbDraw.MouseUp
draw = False
End Sub
Please help me

The line its painting the picturebox

I'm doing a program to make a polygon and fill the outside of it, all of this on an image of a picturebox.
My code is this (I extracted a part of the original and I used and edited the code of VB Helper: Let the user draw polygons in Visual Basic .NET)
Dim Polygons As New List(Of List(Of Point))()
Dim NewPolygon As List(Of Point) = Nothing
Dim NewPoint As Point
Dim bmp As Bitmap
Private Sub khe_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
bmp = New Bitmap(PictureBox1.Width, PictureBox1.Height)
PictureBox1.Image = bmp
End Sub
Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
If (NewPolygon IsNot Nothing) Then
If (e.Button = MouseButtons.Right) Then
If (NewPolygon.Count > 2) Then _
Polygons.Add(NewPolygon)
NewPolygon = Nothing
Else
If (NewPolygon(NewPolygon.Count - 1) <> _
e.Location) Then
NewPolygon.Add(e.Location)
End If
End If
Else
NewPolygon = New List(Of Point)()
NewPoint = e.Location
NewPolygon.Add(e.Location)
End If
PictureBox1.Invalidate()
End Sub
Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
NewPoint = e.Location
PictureBox1.Invalidate()
End Sub
Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
Using myGraphics As Graphics = Graphics.FromImage(PictureBox1.Image)
For Each polygon As List(Of Point) In Polygons
Dim gp As New GraphicsPath
gp.AddPolygon(polygon.ToArray())
Dim rgn As New Region(gp)
myGraphics.ExcludeClip(rgn)
myGraphics.FillRectangle(Brushes.LightPink, Me.ClientRectangle)
myGraphics.DrawPolygon(Pens.SeaShell, polygon.ToArray())
Next polygon
If (NewPolygon IsNot Nothing) Then
If (NewPolygon.Count > 1) Then
myGraphics.DrawLines(Pens.SeaShell, _
NewPolygon.ToArray())
End If
If (NewPolygon.Count > 0) Then
Using dashed_pen As New Pen(Color.Aquamarine, 5)
myGraphics.DrawLine(dashed_pen, _
NewPolygon(NewPolygon.Count - 1), _
NewPoint)
End Using
End If
End If
End Using
End Sub
The problem is this: Initially I was using e.Graphics and the program was working well, but this does not paint the image, rigth? and I changed it, but when I click to start drawing and I move the mouse to set the next point the line is painting the image wherever I move, like this.
This is bad because I want to get a image like this one, and with this problem if I move the mouse on the area I want to keep its going to be painted and the image will be useless.
I'm using Visual Studio 2008 and I'm sorry if my english it's not the best.

Creating New Form Controls in Visual Basic

I am trying to have a button, when clicked, creates a new picturebox control. So that everytime I click it, it adds another new picturebox control. These pictureboxes will all have the same functions like being able to move them around and draw on them. But the button only makes one and no more after that with the following code. What am I missing?
Public Class Form1
Dim xpos As New Integer
Dim ypos As New Integer
Dim pos As New Point
Dim x As Integer
Dim y As Integer
Dim canvas As New PictureBox
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim i As Integer = 0
i = i + 1
canvas.Name = "canvas" & i
canvas.BackColor = Color.White
canvas.BorderStyle = BorderStyle.FixedSingle
canvas.Image = Nothing
canvas.Height = TextBox1.Text
canvas.Width = TextBox2.Text
AddHandler canvas.MouseDown, AddressOf PictureBox1_MouseDown
AddHandler canvas.MouseMove, AddressOf PictureBox1_MouseMove
Controls.Add(canvas)
End Sub
Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
xpos = Cursor.Position.X - canvas.Location.X
ypos = Cursor.Position.Y - canvas.Location.Y
End Sub
Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
If e.Button = Windows.Forms.MouseButtons.Left Then
pos = MousePosition
pos.X = pos.X - xpos
pos.Y = pos.Y - ypos
canvas.Location = pos
End If
End Sub
Private Sub PictureBox1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
End Sub
End Class
Dim canvas As New PictureBox
You have multiple bugs in your code but this is the most serious one. The As New syntax ensures that you'll always create a PictureBox object, but it will only ever be one object. And of course, one variable cannot keep track of multiple picture boxes.
What you need to do is create a new one ever time the button is clicked. It is generally a good idea to keep track of the picture boxes you create. So correct code looks like:
Dim canvases As New List(Of PictureBox)
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim canvas = New PictureBox
canvases.Add(canvas)
canvas.Name = "canvas" & canvases.Count.ToString()
'' etc...
End Sub
Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
Dim canvas = DirectCast(sender, PictureBox)
xpos = Cursor.Position.X - canvas.Location.X
ypos = Cursor.Position.Y - canvas.Location.Y
End Sub
Note how the sender argument gives you a reference back to the picture box object that's being moused. Do the same thing in any other event handlers.
Increasing the counter whenever a new canvas is created:
Public Class Form1
Dim counter As New Integer
...
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
counter += 1
canvas.Name = "canvas" & counter.ToString()
...
Accessing the canvas that the mouse is currently moving over:
Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
If e.Button = Windows.Forms.MouseButtons.Left Then
pos = MousePosition
pos.X = pos.X - xpos
pos.Y = pos.Y - ypos
DirectCast(sender, PictureBox).Location = pos
End If
End Sub

Click and drag implementation on a rectangle VB.NET

So my problem is that I want to have multiple rectangles on a form at a time. However I also want these rectangles to be able to be clicked and dragged across the form.
This is my current code for clicking and dragging a rectangle that was drawn onto the form using the toolbox.
Public Class DragRectangle
Dim Go As Boolean
Dim LeftSet As Boolean
Dim TopSet As Boolean
Dim HoldLeft As Integer
Dim HoldTop As Integer
Dim OffLeft As Integer
Dim OffTop As Integer
Private Sub obj1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles RectangleShape1.MouseUp
Go = False
LeftSet = False
TopSet = False
End Sub
Private Sub obj1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles RectangleShape1.MouseDown
Go = True
End Sub
Private Sub obj1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles RectangleShape1.MouseMove
If Go = True Then
HoldLeft = (Control.MousePosition.X - Me.Left)
HoldTop = (Control.MousePosition.Y - Me.Top)
If TopSet = False Then
OffTop = HoldTop - sender.Top
TopSet = True
End If
If LeftSet = False Then
OffLeft = HoldLeft - sender.Left
LeftSet = True
End If
sender.Left = HoldLeft - OffLeft
sender.Top = HoldTop - OffTop
End If
End Sub
End Class
This works fine for one rectangle, although this requires the rectangles to be pre-drawn onto the form using the toolbox.
What I would like is a rectangle gets drawn by clicking a button on the form, and the newly drawn rectangle can also be clicked and dragged into a new location.
Is this possible?
Thanks for any help
Working example:
Public Class Form1
Private Property Rectangles As New List(Of DrgRectangle)
Private Property curRect As DrgRectangle
Private _x As Integer
Private _y As Integer
Private Sub loadme() Handles Me.Load
'load the rectangle in list
Rectangles.Add(New DrgRectangle With {.Rect = New Rectangle(20, 20, 20, 20)})
End Sub
Private Sub FormMouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown
_x = e.X
_y = e.Y
For Each rect In Rectangles
If rect.Rect.Contains(e.X, e.Y) Then
curRect = rect
Exit For
End If
Next
End Sub
Private Sub FormMouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove
If e.Button = Windows.Forms.MouseButtons.Left Then
If curRect IsNot Nothing Then
curRect.Rect = New Rectangle(New Point(curRect.Rect.Location.X + (e.X - _x), curRect.Rect.Location.Y + (e.Y - _y)), curRect.Rect.Size)
Me.Refresh()
End If
End If
_x = e.X
_y = e.Y
End Sub
Private Sub FormPaint(sender As Object, e As PaintEventArgs) Handles me.Paint
For Each rect In Rectangles
e.Graphics.DrawRectangle(Pens.Black, rect.Rect)
Next
End Sub
End Class
Public Class DrgRectangle
Public Rect As New Rectangle
'add more properties as needed
End Class