Can this code be optimized? Graphics WinForms Vb.Net


I'm new here.

This code is in a form which generates the funds of the form.

I clarify that the form is empty (without controls) and has the DoubleBuffer activated.

I think it consumes too much memory and cpu when executed, maybe it's just the amount of processing that colors / CGI + demand.

' Imports para Graficos
Imports System.Drawing
Imports System.Drawing.Drawing2D

Public Class Form1

    ' Gradient Generator (4 colors) from
    Private Function Gradient2D(ByVal r As Rectangle, ByVal c1 As Color, ByVal c2 As Color, ByVal c3 As Color, ByVal c4 As Color) As Bitmap
        Dim bmp As Bitmap = New Bitmap(r.Width, r.Height)
        Dim delta12R As Double = (1.0! * ((CDbl(c2.R) - c1.R) / r.Height))
        Dim delta12G As Double = (1.0! * ((CDbl(c2.G) - c1.G) / r.Height))
        Dim delta12B As Double = (1.0! * ((CDbl(c2.B) - c1.B) / r.Height))
        Dim delta34R As Double = (1.0! * ((CDbl(c4.R) - c3.R) / r.Height))
        Dim delta34G As Double = (1.0! * ((CDbl(c4.G) - c3.G) / r.Height))
        Dim delta34B As Double = (1.0! * ((CDbl(c4.B) - c3.B) / r.Height))
        Dim G As Graphics = Graphics.FromImage(bmp)
        Dim y As Integer = 0
        Do While (y < r.Height)
            Dim c12 As Color = Color.FromArgb(255, (c1.R + CType((y * delta12R), Integer)), (c1.G + CType((y * delta12G), Integer)), (c1.B + CType((y * delta12B), Integer)))
            Dim c34 As Color = Color.FromArgb(255, (c3.R + CType((y * delta34R), Integer)), (c3.G + CType((y * delta34G), Integer)), (c3.B + CType((y * delta34B), Integer)))
            Dim lgBrush As LinearGradientBrush = New LinearGradientBrush(New Rectangle(0, y, r.Width, 1), c12, c34, 0!)
            G.FillRectangle(lgBrush, 0, y, r.Width, 1)
            y = (y + 1)

        Return bmp
    End Function

    ' Imagen con los gradientes de colores de las esquinas
    Dim bm As New Bitmap(255, 8)

    ' Color Inicial
    Dim c1 As Color
    Dim c2 As Color
    Dim c3 As Color
    Dim c4 As Color
    ' Color Final
    Dim cc1 As Color
    Dim cc2 As Color
    Dim cc3 As Color
    Dim cc4 As Color
    ' Color en uso
    Dim t1 As Color
    Dim t2 As Color
    Dim t3 As Color
    Dim t4 As Color

    ' Operaciones de Dibujo de Formulario
    Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint

        ' Calidad de Graficos: La mas alta
        e.Graphics.CompositingQuality = CompositingQuality.HighQuality

        ' Dibujo de Fondo de Colores
        e.Graphics.DrawImage(Gradient2D(e.ClipRectangle, t1, t2, t3, t4), e.ClipRectangle)

    End Sub

    ' Calculos para determinar nuevos colores
    Dim TimeStart As TimeSpan = Now.TimeOfDay
    Dim TimeDuration As TimeSpan = New TimeSpan(0, 0, 2)
    Sub GenerateNewColors()

        c1 = cc1
        c2 = cc2
        c3 = cc3
        c4 = cc4

        cc1 = RandomColor()
        cc2 = RandomColor()
        cc3 = RandomColor()
        cc4 = RandomColor()

    End Sub

    ' Creador de Colores aleatorios
    Dim r As New Random
    Function RandomColor() As Color
        Return Color.FromArgb(r.Next(0, 256), r.Next(0, 256), r.Next(0, 256))
    End Function

 ' Calculos para determinar color actual
    Dim x As Integer, g As Graphics = Graphics.FromImage(bm)
    Dim br As New LinearGradientBrush(New Rectangle(0, 0, 255, 2), c1, cc1, 0, False)
    Sub SetTemps()

        If Now.TimeOfDay > (TimeStart + TimeDuration) Then
            TimeStart = Now.TimeOfDay

            ' g.Clear(Color.White)
            br.LinearColors = {c1, cc1}
            g.FillRectangle(br, New Rectangle(0, 0, 255, 2))

                br.LinearColors = {c2, cc2}
                g.FillRectangle(br, New Rectangle(0, 2, 255, 2))

                br.LinearColors = {c3, cc3}
                g.FillRectangle(br, New Rectangle(0, 4, 255, 2))

                br.LinearColors = {c4, cc4}
                g.FillRectangle(br, New Rectangle(0, 6, 255, 2))

        End If
        x = (CInt((Now.TimeOfDay - TimeStart).TotalSeconds * 255) / (TimeDuration.TotalSeconds))
        If x >= 255 Then x = 254
        t1 = bm.GetPixel(x, 0)
        t2 = bm.GetPixel(x, 2)
        t3 = bm.GetPixel(x, 4)
        t4 = bm.GetPixel(x, 6)

    End Sub

    ' Load
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
        ResizeRedraw = True
    End Sub

    ' Show (Loop)
    Dim stopAll As Boolean = False
    Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
        While stopAll = False


        End While
    End Sub

    Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
        stopAll = True
    End Sub

End Class

Now I leave the images with the consumption:

So my question is: is this excessive amount (if you can call it that) of CPU and RAM consumption inevitable for these graphics operations? I forgot to empty the resources somewhere? Is there another option with similar results that recommend me to get this kind of graphics?

Thank you very much for your attention. Atte, Pablo.

asked by Pablo Fac 23.03.2018 в 06:58

1 answer


To avoid memory leaks you should always use Dispose in the classes that implement the IDisposable interface, either manually, or using the Using structure. For example, you make g As Graphics = Graphics.FromImage(bm) . When you finish with g , you must release the resources using g.Dispose() , or better yet, include all the code with:

Using g As Graphics.FromImage(bm)
    ' .....
End Using

This means that once you finish working with the objects, the memory is correctly discarded. Only with that should you notice a noticeable improvement.

answered by 26.03.2018 / 09:06