שתף באמצעות


Sending graphics to a picturebox

Question

Monday, July 9, 2018 3:47 AM

Hi my name is Les. I have been trying to learn about the various parameters that are in some objects and the events that are available within them. I am making progress but have a lack of a full understanding about what I would like to do. I have enclosed my code snippet which in fact is what I want to do but want it on a picturebox. Because I don't have a full understanding as to how it all gets tied together I come humbly here. I have tried Barnes & Nobel for some good books on this subject and believe it or not they have none that are available and that I have to just buy and hope it has what I need. If by chance someone can mention a good book on the various things we can do with graphics like I am looking to do I would appreciate it. Ok I have enclosed my code.

    Private Sub form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
        ' Make the font. Use Pixels as the unit.
        Dim FONT_SIZE As Integer
        FONT_SIZE = 100
        Dim the_font As New Font("Times New Roman", FONT_SIZE, FontStyle.Regular, GraphicsUnit.Pixel)
        ' Make the text origin and StringFormat.
        Dim sf As New StringFormat
        Dim origin As New PointF(100, 200)
        origin.X = 100
        origin.Y = 200
        ' Add the text to the GraphicsPath.
        Dim text_path As New GraphicsPath
        Dim a As SizeF
        Dim t As String

        Dim text_rectf As RectangleF = text_path.GetBounds()
        Dim text_rect As Rectangle = Rectangle.Round(text_rectf)

        t = "f(x)=12x"
        FONT_SIZE = 100
        a = e.Graphics.MeasureString(t, New Font("Times New Roman", FONT_SIZE, FontStyle.Regular, GraphicsUnit.Pixel))
        origin.X = 0
        text_path.AddString(t, the_font.FontFamily, CInt(FontStyle.Regular), FONT_SIZE, origin, sf)

        ' Draw the text.
        e.Graphics.SmoothingMode = SmoothingMode.AntiAlias
        e.Graphics.FillPath(Brushes.Black, text_path)
        e.Graphics.DrawPath(Pens.Black, text_path)

        ' Draw the bounding rectangle.
        text_rectf = text_path.GetBounds()
        text_rect = Rectangle.Round(text_rectf)
        e.Graphics.DrawRectangle(Pens.Red, text_rect)

        origin.X = text_rect.Width + 15
        t = "2"
        FONT_SIZE = 50
        a = e.Graphics.MeasureString(t, New Font("Times New Roman", FONT_SIZE, FontStyle.Regular, GraphicsUnit.Pixel))
        text_path.AddString(t, the_font.FontFamily, CInt(FontStyle.Regular), FONT_SIZE, origin, sf)

        ' Draw the text.
        e.Graphics.SmoothingMode = SmoothingMode.AntiAlias
        e.Graphics.FillPath(Brushes.Black, text_path)
        e.Graphics.DrawPath(Pens.Black, text_path)

        ' Draw the bounding rectangle.
        text_rectf = text_path.GetBounds()
        text_rect = Rectangle.Round(text_rectf)
        e.Graphics.DrawRectangle(Pens.Red, text_rect)

        t = "-5x+3"
        FONT_SIZE = 100
        a = e.Graphics.MeasureString(t, New Font("Times New Roman", FONT_SIZE, FontStyle.Regular, GraphicsUnit.Pixel))
        origin.X = text_rect.Width
        text_path.AddString(t, the_font.FontFamily, CInt(FontStyle.Regular), FONT_SIZE, origin, sf)

        ' Draw the text.
        e.Graphics.SmoothingMode = SmoothingMode.AntiAlias
        e.Graphics.FillPath(Brushes.Black, text_path)
        e.Graphics.DrawPath(Pens.Black, text_path)

        ' Draw the bounding rectangle.
        text_rectf = text_path.GetBounds()
        text_rect = Rectangle.Round(text_rectf)
        e.Graphics.DrawRectangle(Pens.Red, text_rect)


        ' Cleanup.
        sf.Dispose()
        the_font.Dispose()

    End Sub

What this code does at the moment is it draws what I want but it goes onto the form and not the picturebox since the code is in that form object.  Now I can get it into the picturebox successfully but what I want to do is be able to write my code in lets say some command button and have it send the graphics to the paint event within the picturebox.  Can someone get me started here so that I can get an understanding how to do this?

Thank you for your help in advance,

Les

All replies (16)

Tuesday, July 10, 2018 12:37 AM ✅Answered

Hi Les,

You can achieve your goal with any of the suggested solutions; I'll let you play around to decide what works best for you and ask questions as needed.

As for a book, in my experience, they are all pretty bad.  I've never seen a good book on VB.Net and if it wasn't published in the last year or so, its probably full of dated material anyway.

My suggestion is the MSDN documentation.  Press F1 on everything in your code.  Use intellisense to just look through the members of an object after pressing the period key after an object, or browse through the Object Browser window.  When something peeks your curiosity, press F1 to jump to the help.  Also check for help topics and walkthroughs on specific technologies.  This link is probably a good starting point for graphics:
/en-us/dotnet/framework/winforms/advanced/about-gdi-managed-code

Keep following links and moving through the new docs site (pay attention to the layout of the page linked above, that is how you know you are in the new docs pages versus the old ones which look more like the old HTML help files).  If you come to a page that isn't helpful or find circular references that don't get you to what you are looking for, let me know.  The docs are under active development and improvement so now is a great time to point out any weakness or ways to make them better and I can get your comments directly to the team involved or show how to contribute suggestions/changes yourself (Visual Studio documentation is part of the Microsoft Open Source initiative https://github.com/MicrosoftDocs/). You can submit feedback directly to the issues page, or like I say, let me know, and I can forward it onto the team or create the issue for you.

Reed Kimble - "When you do things right, people won't be sure you've done anything at all"


Monday, July 9, 2018 4:40 AM | 1 vote

Try the next approach:

*   Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click*

*      Dim image As New Bitmap(500, 400)*

*      Using g = Graphics.FromImage(image)*

*         . . .*

*      End Using*

*      PictureBox1.Image = image*

*   End Sub*

where “…” is your current code from form1_Paint (which must be removed), replacing e.Graphics with g. Choose the right size for the image and picture box.


Monday, July 9, 2018 5:28 AM

Hi Viorel

Well first thx for helping here but I think there is a misunderstanding.  I prefer not to draw it into a bitmap and then send it over to the picturebox.  The reason is I will never know the size I need ahead of time and would rather not have to estimate the size of the picturebox I will need.  Is there a way of doing the initial work how I did it?  What I mean is from somewhere else can I write the equation and yet send it to the picturebox??  I don't know if I am making it clear.  Basically I would rather do my work in some kind of function or sub and send it to the picturebox sine I will need to keep track of the size of the graphics as I am building the equation.  Keep in mind the size of my equation will always be different in height and width and thought using the method I coded allows me to do that.

Hopefully that explains it a bit more clearly,

Les


Monday, July 9, 2018 5:57 AM | 1 vote

Hi Les

I think Viorel means this:

Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint
 Dim bmp As Bitmap = New Bitmap(200, 500)
        Dim g As Graphics = Graphics.FromImage(bmp)
              .
              .
              .

 ' Draw the text.
        e.Graphics.FillPath(Brushes.Black, text_path)
        e.Graphics.DrawPath(Pens.Black, text_path)
        g.FillPath(Brushes.Black, text_path)
        g.DrawPath(Pens.Black, text_path)
 
              .
              .
              .
 
PictureBox1.Image = bmp

Best Regards

Alex

MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


Monday, July 9, 2018 6:34 AM

Hi Alex

Thank you for trying to help here but with either method how will I keep track of the width and height of whatever the equation is?? With the rectangles in my code I can get the height and width so I can make the picture box the size to totally contain the image and since the picturebox will be placed into a panel control I get to use the scrollbars within which allows me to scroll either up down or in both directions to see all the math within the picturebox.  Keep in mind Alex that I may have many lines of equations of all different heights and lengths and as long as I keep track of that and adjust the picturebox height and width I will be able to scroll inside the panelbox.  Now please understand that regarding the use of graphics I am relatively new and trying very hard to understand it all.

Please bare with me,

Les


Monday, July 9, 2018 5:04 PM

Hi TTT,

Ok I have put a gif file together to show you what my needs are from a graphics perspective.  I have worked out all the coding aspects to make sure everything is centered to perfection and so forth.  I just don't understand why you recommend doing my graphics first and then sending it to the picturebox canvas without knowing the exact size of my surrounding rectangle around the whole thing.

Once again thank you so much for your assistance

Les


Monday, July 9, 2018 5:47 PM | 1 vote

I just don't understand why you recommend doing my graphics first and then sending it to the picturebox canvas without knowing the exact size of my surrounding rectangle around the whole thing.

Because it is relatively simple to scale the output to fit the picturebox.

If you are wanting to generate a text-heavy image (as the image you posted would indicate) then you do have to be more careful with scaling so the text remains readable.  But in that case, how do you want to handle a wide image?  What if it is too wide to fit in the form?  Will you allow scrolling, or scaling, shrink the font, or do you have some other solution in mind?

Reed Kimble - "When you do things right, people won't be sure you've done anything at all"


Monday, July 9, 2018 6:38 PM


Monday, July 9, 2018 11:53 PM

Hi Reed

Yes scaling will definitely screw up the formatting which my coding takes care of the best it can.  The way I handle it since every equation can be different as far as length and height and may have many lines to the solution I track of the max height and width which is used to govern the placement of the next line of equations.  Keep in mind I will also have square roots of varying sizes etc.  What I do is I make the size of my picturebox equal to the height and width and the picturebox is enclosed in a panelbox which I set scrollbars on.  So regardless of how large my picturebox gets the panelbox scrollbars take care of the scrolling for me.  Hopefully I answered your question.  I can see by your comments you do understand the problems with scaling if I were to do it the opposite way.

Thank you Reed

Les


Monday, July 9, 2018 11:58 PM

Hi Reed very nicely done and I find it educational.  As I stated in your prior comments the equations will get longer then the picturebox or form will hold and therefore I want the opportunity to scroll.  I thank you so much for your description in helping me learn these aspects of vb and will keep your code in my folder labeled vb help.

Let me do a little more playing reed and I will tell you what I come up with or will be back yelling for more of your technical savviness.  You guys here have always been patient with me over the years and without the help I would be still struggling with vb.

Les


Tuesday, July 10, 2018 12:05 AM

HI TTT

You have an excellent memory and you are right.  I stopped the development of this app back many years ago, to hectic with all my real work I do for a living.  After major surgery in 2017 which kept me out of work for 7 months my birthday was this past June 12th and I announced my retirement on June 13th <S>.  FYI I did tell the company I was doing my chemical R7D three years ago that this was going to be my date so it had nothing to do with my surgery.  Now its time to really learn vb.net and have fun.  MAybe I will have an opportunity to know enough about it where I can help someone else like you guys.  BTW I cant seem to find a good book that emphasizes this kind of stuff.  I want to understand what to do with the paramenters inside the routines like e.graphics etc and if you could suggest any I would really appreciate it.  I got plenty of time now to learn.

As far as what Viorels method does I don't think it will be a clean way to what I am trying to do but with all these repsonses and suggestions I feel as though I am gaining more info to my learning curve.

Nice code TTT

Thanks

Les


Tuesday, July 10, 2018 1:14 AM

Thank you very much Reed for your input and vast knowledge.  I have to say I echo your comments on a good VB book, it just does not seem to exist surprisingly.  I went to Barnes & Nobel to look for a book a few weeks ago and although they had several vb books on line they had noting in the store. I asked the manager if he can order them into the store so I can look at them to decide what I want to purchase and he said anything on vb if you order into the store you must buy it.  I asked him even with nothing as about the book and just on good faith he said yes!! Terrible.  I will take your advice and start going throught things thx Reed.

Les


Tuesday, July 10, 2018 5:27 AM

Hi Reed one more thing.  Is there a way of instead of doing my graphics directly in the paint event of the Picturebox and I do them in lets say a button_click which generates the equation and then sends it to the picturebox?  Basically do what I have done in my code section but in a button instead of dong it directly in a picturebox paint event?  My thought is I probably want to display one step at a time of the equations solution by having the end user click a button that may say next step or something to that affect. If I cant I am sure I will figure a way to do it.

Thx

Les


Tuesday, July 10, 2018 11:43 AM

Hi Reed one more thing.  Is there a way of instead of doing my graphics directly in the paint event of the Picturebox and I do them in lets say a button_click which generates the equation and then sends it to the picturebox?  Basically do what I have done in my code section but in a button instead of dong it directly in a picturebox paint event?  My thought is I probably want to display one step at a time of the equations solution by having the end user click a button that may say next step or something to that affect. If I cant I am sure I will figure a way to do it.

Thx

Les

One way would be by drawing to a bitmap instance first, then displaying the bitmap.  That way you could add new content to the bitmap on each click of the button.

Another way would be to treat the drawing routine like vector graphics; essentially you build a list of commands that define what to draw.  Then you add a new drawing command to the list when the button is clicked and refresh the PictureBox.  When the Paint method executes, it now shows the new content from the command list.

Reed Kimble - "When you do things right, people won't be sure you've done anything at all"


Tuesday, July 10, 2018 11:46 AM | 1 vote

Tommy,

Why did you drop out of the thread?  Your contributions were useful and you wiped out the proposed solution… Les even commented that your code was useful, but now he cannot continue to study it.  If you still have that example, I'd encourage you to please put it back.

Reed Kimble - "When you do things right, people won't be sure you've done anything at all"


Sunday, July 15, 2018 5:08 AM

Hi Reed,

First let me thank you for these links, I can see I have a lot of work to do <S> but its beginning to make some sense.  I started in a very preliminary way exploring some of the things you and others here have suggested and I feel as though I am getting close to getting SOME of it.  One big question is the following.  BTW I am not steering away from yours and others suggestions but I want to know is there a way of resizing a graphics buffer once it has been generated or perhaps there is another way around it.  Let me show you my tiny shot at the coding.  Now this is close to what I am trying to do Reed let me explain.  Say I have 6 lines of equations of all different lengths.  What I am doing or want to do is keep track of the longest length and set my picture box width and height which is in a panel with scrollbars.  This guarantees me that the picturebox is close to exactly the longest length of my equations which all the others would be fine to fit and I plan on doing the same with the height.  I do not want to have a graphics buffer that is longer or higher then necessary.  So my thought is if I do what I did in the code here with setting the initial size of the graphics buffer (which initially can be well oversized) but then when I am done generating all my lines of equations and determine the exact size I need that I can then shrink the buffer to the exact size I need by the values I will be tracking for height and width.  I am hoping that there should be a way of shrinking it but so many times it gets more complicating <S>.

Oh BTW you know what I find difficult is knowing when to add the various things as Imports, just my 2cents

Thank you,

Les

Imports System.Drawing.Drawing2D
Imports System.Drawing

Public Class Form1
    Dim backbuffer As New Bitmap(309, 175)

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Dim g As Graphics
        g = Graphics.FromImage(backbuffer)
        g.Clear(Color.White)
        g.DrawRectangle(Pens.Blue, New Rectangle(New Point(0, 0), New Size(100, 100)))
        Dim tag As String = "f(x)=12x^2-8x+2"
        g.DrawString(tag, New Font("Calibri", 36, FontStyle.Regular), New SolidBrush(Color.Black), New Point)
        PictureBox1.CreateGraphics.DrawImage(backbuffer, New Point(0, 0))
    End Sub