Solved

How do I draw over an image inside a panel?

Posted on 2009-04-09
11
263 Views
Last Modified: 2013-11-26
I made this application for placing points (x,y) on an image. To make it scrollable, I placed the picturebox inside a panel. Ive tried two different approaches.

Approach 1 is the simplest.
The problem is that after I place an image, when I put a point (or points), when I scroll the image the points disappeare.
How do I keep the points from disapearing? I only want them to disapear when another image is loaded into the picture box.

Approach 2
The problem here is that when I place the points, they shift towards the center.
Why do they points shift and how can I fix this?


'Approach 1 *************************************************************************************************'
Public Class Landmarks
 
    Dim ima, ext As String
    Dim picsize(2) As Integer
    Dim x, y As Integer
    Dim Img As Image
 
    Private Sub PicBox_Click(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PicBox.Click
 
        Dim graph As Graphics = PicBox.CreateGraphics
        Dim coordinate As String
        x = e.X
        y = (-1) * (e.Y) + PicBox.Height - 5
        coordinate = CStr(x) & " " & CStr(y)
        ListBox1.Items.Add(coordinate) 'adds x to listbox 1'
        graph.FillEllipse(Brushes.Blue, e.X - 3, e.Y - 3, 5, 5) 'adds a filled circle in the picturebox '
        graph.DrawEllipse(Pens.Blue, e.X - 6, e.Y - 6, 11, 11) 'adds a ring around the filled circle'
 
    End Sub
 
    Private Sub OpenFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OpenFile.Click
        ima = " "
        ext = " "
        If OpenFileDialog1.ShowDialog() = DialogResult.OK Then
            ima = OpenFileDialog1.FileName
            PicBox.Enabled = True
            picsize(0) = Image.FromFile(ima).Height 'Stores the height of the picture'
            picsize(1) = Image.FromFile(ima).Width ' stores the width of the picture'
            PicBox.Height = picsize(0) 'sets the height of the picturebox = height of the picture'
            PicBox.Width = picsize(1) 'sets the width of the picturebox = width of the picture'
            PicBox.Image = Image.FromFile(ima) 'puts the picture into the picturebox'
            Img = Image.FromFile(ima)
 
        Else
            MsgBox("The extension is not supported.")
        End If
    End Sub
 
    Private Sub PicBox_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PicBox.MouseMove
        x = e.X
        y = (-1) * (e.Y) + PicBox.Height - 5
        coor.Text = CStr(x) & " " & CStr(y)
    End Sub
 
    Private Sub PicBox_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PicBox.Click
 
    End Sub
End Class
'****************************************************************************************************************************'
 
 
 
'Approach 2 *********************************************************************************************************'
Public Class Landmarks
 
    Dim ima, ext As String
    Dim picsize(2) As Integer
    Dim x, y As Integer
    Dim Img As Image
 
    Private Sub PicBox_Click(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PicBox.Click
 
        Dim bmp As New System.Drawing.Bitmap(Img)
        Dim graph As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(bmp)
        Dim coordinate As String
        x = e.X
        y = (-1) * (e.Y) + PicBox.Height - 5
        coordinate = CStr(x) & " " & CStr(y)
        ListBox1.Items.Add(coordinate) 'adds x to listbox 1'
        graph.FillEllipse(Brushes.Blue, e.X - 3, e.Y - 3, 5, 5) 'adds a filled circle in the picturebox '
        graph.DrawEllipse(Pens.Blue, e.X - 6, e.Y - 6, 11, 11) 'adds a ring around the filled circle'
        Img = bmp.Clone
        PicBox.Image = Img
    End Sub
 
    Private Sub OpenFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OpenFile.Click
        ima = " "
        ext = " "
        If OpenFileDialog1.ShowDialog() = DialogResult.OK Then
            ima = OpenFileDialog1.FileName
            PicBox.Enabled = True
            picsize(0) = Image.FromFile(ima).Height 'Stores the height of the picture'
            picsize(1) = Image.FromFile(ima).Width ' stores the width of the picture'
            PicBox.Height = picsize(0) 'sets the height of the picturebox = height of the picture'
            PicBox.Width = picsize(1) 'sets the width of the picturebox = width of the picture'
            PicBox.Image = Image.FromFile(ima) 'puts the picture into the picturebox'
            Img = Image.FromFile(ima)
 
        Else
            MsgBox("The extension is not supported.")
        End If
    End Sub
 
    Private Sub PicBox_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PicBox.MouseMove
        x = e.X
        y = (-1) * (e.Y) + PicBox.Height - 5
        coor.Text = CStr(x) & " " & CStr(y)
    End Sub
 
    Private Sub PicBox_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PicBox.Click
 
    End Sub
End Class
 
'****************************************************************************************************************************************

Open in new window

0
Comment
Question by:iron_guitarist1987
  • 5
  • 4
  • 2
11 Comments
 
LVL 85

Accepted Solution

by:
Mike Tomlinson earned 350 total points
ID: 24113859
Try this simple project out...
Public Class Form1
 
    Private marks As New List(Of Point)
 
    Private Sub PictureBox1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PictureBox1.Click
        marks.Add(PictureBox1.PointToClient(Cursor.Position))
        PictureBox1.Refresh()
    End Sub
 
    Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
        For Each pt As Point In marks
            Dim rc As Rectangle = New Rectangle(pt.X, pt.Y, 1, 1)
            rc.Inflate(6, 6)
            e.Graphics.FillEllipse(Brushes.Red, rc)
        Next
    End Sub
 
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        ' clear all the marks
        marks.Clear()
        PictureBox1.Refresh()
    End Sub
 
End Class

Open in new window

0
 

Author Comment

by:iron_guitarist1987
ID: 24116615
Thanks, but the points are still being shifted.
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 24117279
It's working fine for me.

See the series of images below:
(1) No Marks
(2) I placed Marks on the characters Eyes
(3) I scrolled the Image Down and to the Right.  The Marks are still on their eyes in the proper place.

Marks1.jpg
Marks2.jpg
Marks3.jpg
0
The New “Normal” in Modern Enterprise Operations

DevOps for the modern enterprise offers many benefits — increased agility, productivity, and more, but digital transformation isn’t easy, especially if you’re not addressing the right issues. Register for the webinar to dive into the “new normal” for enterprise modern ops.

 
LVL 83

Expert Comment

by:CodeCruiser
ID: 24118013
I think another approach would be to add the marks to the image itself instead of the picturebox. So create the graphics for the image like this

Dim graph As Graphics = Graphics.FromImage(PicBox.Image)
0
 

Author Comment

by:iron_guitarist1987
ID: 24118020
Ok, I got to work. Thanks a billion!
0
 

Author Comment

by:iron_guitarist1987
ID: 24118314
Ok, now I need a way to delete just one of them at a time. What I do in my code is, since I store the positions as a string in a listbox, what I do is a clear all of the marks and then I place them one by one using the values in the listbox. My question is: How can I use the instruction:

marks.Add(PictureBox1.PointToClient(Cursor.Position))

but use a string (xvalue yvalue) as an input instead of cursor.position
0
 
LVL 83

Expert Comment

by:CodeCruiser
ID: 24118356
I do not fully understand your question but i think if you maintain a copy of the image then you can always start from scratch again.
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 24118366
You would need to create a Point() from the String in your ListBox:
        Dim x, y As Integer
        Dim coords As String = "25 50" ' <-- get it from your ListBox somehow
        Dim values() As String = coords.Split(" ")
        If values.Length = 2 AndAlso Integer.TryParse(values(0), x) AndAlso Integer.TryParse(values(1), y) Then
            Dim pt As New Point(x, y)
            marks.Add(pt)
            PictureBox1.Refresh()
        End If

Open in new window

0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 24118451
To your previous comment:

    "Ok, now I need a way to delete just one of them at a time."

See my code here:
http://www.experts-exchange.com/Programming/Languages/Visual_Basic/Q_24144379.html#23651755
0
 

Author Comment

by:iron_guitarist1987
ID: 24118548
Great! thanks a million!
0
 

Author Closing Comment

by:iron_guitarist1987
ID: 31568658
The code works perfectly. Thank you very much!
0

Featured Post

The New “Normal” in Modern Enterprise Operations

DevOps for the modern enterprise offers many benefits — increased agility, productivity, and more, but digital transformation isn’t easy, especially if you’re not addressing the right issues. Register for the webinar to dive into the “new normal” for enterprise modern ops.

Question has a verified solution.

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

For those of you who don't follow the news, or just happen to live under rocks, Microsoft Research released a beta SDK (http://www.microsoft.com/en-us/download/details.aspx?id=27876) for the Xbox 360 Kinect. If you don't know what a Kinect is (http:…
A long time ago (May 2011), I have written an article showing you how to create a DLL using Visual Studio 2005 to be hosted in SQL Server 2005. That was valid at that time and it is still valid if you are still using these versions. You can still re…
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

820 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