Quantcast
Channel: paint event on picturebox
Viewing all articles
Browse latest Browse all 48

paint event on picturebox

$
0
0

Hy tommy2train,

i have checked your code setting 100000 points, the refreshing speed seems to be the same.

If i have well understood, at every tick all points are drawn; notwistanding this, it seems to be indipendent from their number.

Best regards, Enzo

Enzo,

The example that draws on a bitmap only draws the new point each clock tick, not all points. This what you did it in vb6.

That is the key to understand. See the bitmap? See there is only one point (line) drawn and in the timer event on the bitmap. Then the bitmap is shown.

The second example (above) is drawing in the paint event and draws all points each tick. See the for loop in the paint event that draws all the points (lines) each tick?

So the bitmap example draws one point each tick. The Paint event draws all the points (up to 30000 max at the end)  each tick.

Comprende?

As Enzo has correctly infered eventually there will be enough points that the paint event draw all points method will be slower. Even if it takes 1,000,000 points the one drawing all points each tick  will be slower. That is Enzo's question and logic. Not which faster but which is more efficient.

The two different examples prove the difference in the two different methods. That is all. 

 

Yes Les you are correct one does not need to draw 30000 points the curve can be drawn with 1000. If all 30000 pts were drawn in an empty pixel the image would fill the picturebox. That is not the point.

Yes Castor your are correcct DirectX is faster. That is not the question.

 

Here is the draw only new points on bitmap example. This has just a couple additions from the version above.

The example makes the controls just copy and paste the code into an empty form. Change the form name as required.

 

'draw one point each tick on bitmap v2
Public Class Form7
    Private WithEvents Timer1 As New Timer With {.Interval = 10}
    Private WithEvents Button1 As New Button With {.Parent = Me, .Text = "Start",
            .Location = New Point(20, 20), .ForeColor = Color.AntiqueWhite, .BackColor = Color.ForestGreen}
    Private WithEvents PictureBox1 As New PictureBox With {.Parent = Me,
        .BackColor = Color.Black, .BorderStyle = BorderStyle.FixedSingle}
    Private deltax, deltay As Single
    Private offset As Single
    Private count As Integer
    Private points(30000) As Single
    Private Sw As New Stopwatch
    Private Frames As Integer
    Private PicBmp As Bitmap
    Private PicG As Graphics
    Private x1 As Single = 0

    Private Sub Form6_Load(sender As Object, e As EventArgs) Handles Me.Load
        Text = "Draw on Bitmap"
        ClientSize = New Size(500, 300)

        Form6_Resize(0, Nothing)
    End Sub

    Private Sub Form6_Resize(sender As Object, e As EventArgs) Handles Me.Resize
        Dim border As Integer = 20

        PictureBox1.Top = Button1.Bottom + border
        PictureBox1.Left = border
        PictureBox1.Width = ClientSize.Width - (2 * border)
        PictureBox1.Height = ClientSize.Height - (PictureBox1.Top + border)

        PicBmp = New Bitmap(PictureBox1.ClientSize.Width, PictureBox1.ClientSize.Height)
        PicG = Graphics.FromImage(PicBmp)

        deltay = PicBmp.Height
        deltax = CSng(PicBmp.Width / points.Length)
        offset = CSng(PicBmp.Height / 2)

        If PictureBox1.Image IsNot Nothing Then PictureBox1.Image.Dispose()
        PictureBox1.Image = PicBmp

    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        x1 = 0
        count = 0
        Frames = 0
        Sw.Reset()
        Sw.Start()
        Timer1.Interval = 10
        Timer1.Enabled = True
    End Sub

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        Dim fps As String = "0.0"
        Static nexttime As Long

        count = count + 1
        points(count) = CSng((deltay * 0.3 * Math.Sin((10 / points.Length) * count)) + offset)

        If count > points.Length - 2 Then
            Timer1.Stop()
            'Using bmp As New Bitmap(PictureBox1.ClientSize.Width, PictureBox1.ClientSize.Height)
            '    PictureBox1.DrawToBitmap(bmp, New Rectangle(0, 0, bmp.Width, bmp.Height))
            '    bmp.Save("c:\test\bitmap1.png")
            'End Using
        End If

        With PicG

            'show time every 500 ms
            Frames += 1
            fps = (Frames / (nexttime / 1000)).ToString("f1")

            If Sw.ElapsedMilliseconds > nexttime Then
                nexttime = Sw.ElapsedMilliseconds + 500
            End If

            .SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
            .FillRectangle(Brushes.Black, 0, 0, PictureBox1.ClientSize.Width, 30)
            .DrawString(count.ToString & " - " &
                 fps & " fps  " & (nexttime / 100).ToString("f0") & " secs",
                 Me.Font, Brushes.White, 10, 10)

            If count > 1 Then
                .DrawLine(Pens.Red, x1, points(count - 1), x1 + deltax, points(count))
            End If

            x1 += deltax

        End With

        PictureBox1.Invalidate()

    End Sub
End Class

 

Enzo,

See how there is no paint event code in the above draw on bitmap v2 example?

See where the bitmap is declared at class level at the top?

 

    Private PicBmp As Bitmap
    Private PicG As Graphics
 

Also see how the PicG is graphics surface is created from thePicBmp in the resize event (thus you can resize the form).

    PicBmp = New Bitmap(PictureBox1.ClientSize.Width, PictureBox1.ClientSize.Height)
    PicG = Graphics.FromImage(PicBmp)
 

With the draw on bitmap method, we draw on PicG the graphics surface for the bitmap in the timer tick event sub routine. Since we draw on a bitmap theimage is saved on the bitmap and we don't redraw it each tick. Instead we only draw the new points on the previously drawn bitmap and then .invalidate to copy the bitmap it to the screen.

In the draw in paint event sub routine we use e.graphics to drawon. The paint event is called each timer tick. The system clears the previous drawingand we redraw all the points again.

See the difference? One method we are saving the previously drawn image in the bitmap.The other method the system is clearing the image by giving us an empty bitmap e.graphics to draw on and we need to redraw the entire image all points each tick.

In most cases one only needs to draw in the paint event. If you filter your number of points (as Les showed) that is all you need.

Finally, I answered the question not you Enzo. The correct answer is my post showing the example code. You should mark my post as the answer not yours.

Adios



Viewing all articles
Browse latest Browse all 48

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>