IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB.NET Discussion :

Decoupage graphic en GDI+


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    valves hydrauliques
    Inscrit en
    Septembre 2006
    Messages
    68
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : valves hydrauliques
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2006
    Messages : 68
    Par défaut Decoupage graphic en GDI+
    Bonjour,

    j'ai develope il y a quelque temps avec votre aide un afficher de courbes de mesures en VB2008 et GDI+. Il fonctionne super bien, mais avac la quantite de donnees a afficher (souvent largement plus de 100.000pts) la regeneration de l'ecran quand on veut deplacer la partie visible sur l'ecran devient lent.
    Mon idee serais de creer un objet en memoire dans lequel on trace toute la courbe, et pour afficher la partie visible on copie la partie souhaitee sur l'ecran : par exemple on a une mesure sur 100sec, mais on affiche que entre 10sec et 12sec, puis on se decalle et on veut voir entre 11 et 13, etc. . ce decallage bien sur par un mouvement de la souris bien fluide.

    J'utilise un bufferedgraphics, donc l'idee serais d'avoir un buffer tres grand et de transferer par render juste une petite partie sur le graphics de l'objet du formulaire.
    Mais comment faire ce decoupage au moment de la fonction render (ou tout autre procedee qui marche ?

    Ici en tres simplifie comment je procede actuellement pour dessiner sur Panel1

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    ' activer le system de buffer graphics double
     SetStyle(System.Windows.Forms.ControlStyles.OptimizedDoubleBuffer, True)
     ContextGraph = BufferedGraphicsManager.Current
     ContextGraph.MaximumBuffer = New Size(Panel1.Width, Panel1.Height)
     
    ' recuper le graphics de la surface de dessin
      GraphicsControl = Panel1.CreateGraphics
     
    ' dimensioner le buffergraph
      BufferGraph = ContextGraph.Allocate(GraphicsControl, New Rectangle(0, 0, Panel1.Width, Panel1.Height))
     
    ' effacer fond
     BufferGraph.Graphics.FillRectangle(Brushes.Beige, 0, 0, Panel1.Width, Panel1.Height)
     GraphicsControl.FillRectangle(Brushes.Beige, 0, 0, Panel1.Width, Panel1.Height)
     
    ' dessiner
     For i = 0 To 1000 Step 10
         BufferGraph.Graphics.DrawLine(Pens.Black, 0, 0, i * 10, 1000)
     Next
     
    ' envoyer dessin sur l'閏ran
     BufferGraph.Render(GraphicsControl)
    Merci de votre aide

    (Je suis en chine, ici pas d'accents sur le clavier, donc mes excuses)

  2. #2
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut
    Bonjour armin
    Est-ce que tu as pense à un bitmap?....
    Ton objet graphique serait tout simplement un bitmap aussi grand que tu voudras ensuite c'est le bitmap que tu dessineras dans l'event paint du panel......................
    Cela permets de faire defiler avec des scrollbars le bitmap dans le panel.....
    le code de ton custom panel:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
     
    Imports System.ComponentModel
     
    Public Class CustomPanel
        Inherits Panel
        Private bmp As Bitmap
        Private GraphicsControl As Graphics
     
     
        Public Sub New()
            ' Cet appel est requis par le Concepteur Windows Form.
            InitializeComponent()
     
            ' Ajoutez une initialisation quelconque après l'appel InitializeComponent().
     
            Me.AutoScroll = True
            Me.AutoScrollMinSize = New Size(1072, 768)
     
            'cree un bitmap en memoire et fait le "rendu" 
            LoadCurrentMap()
     
        End Sub
     
        Private Sub LoadCurrentMap()
            bmp = New Bitmap(Me.Width * ScaleX, Me.Height * ScaleY)
            ' recuper le graphics de la surface de dessin
            GraphicsControl = Graphics.FromImage(bmp)
            renderBitmap(GraphicsControl, bmp)
        End Sub
        Private Sub renderBitmap(ByVal GraphicsControl As Graphics, ByVal currentBmp As Bitmap)
            Dim ContextGraph As BufferedGraphicsContext = BufferedGraphicsManager.Current
            ContextGraph.MaximumBuffer = New Size(currentBmp.Width, currentBmp.Height)
            ' dimensioner le buffergraph
            Dim BufferGraph As BufferedGraphics = ContextGraph.Allocate(GraphicsControl, New Rectangle(0, 0, currentBmp.Width, currentBmp.Height))
     
            ' effacer fond
            BufferGraph.Graphics.FillRectangle(Brushes.Beige, 0, 0, currentBmp.Width, currentBmp.Height)
            GraphicsControl.FillRectangle(Brushes.Beige, 0, 0, currentBmp.Width, currentBmp.Height)
     
            ' dessiner
            For i = 0 To 1000 Step 10
                BufferGraph.Graphics.DrawLine(Pens.Black, 0, 0, i * 10, 1000)
            Next
     
            ' envoyer dessin 
            BufferGraph.Render()
            BufferGraph.Render(GraphicsControl)
            BufferGraph.Dispose()
            Me.Invalidate()
        End Sub
        Private m_ScaleX As Integer = 1.0
        <Browsable(True)> _
        <Category("Divers")> _
        Public Property ScaleX() As Integer
            Get
                Return m_ScaleX
            End Get
            Set(ByVal Value As Integer)
                If Value < 0 Then
                    m_ScaleX = 1.0
                Else
                    m_ScaleX = Value
                End If
            End Set
        End Property
        Private m_ScaleY As Integer = 1.0
        <Browsable(True)> _
       <Category("Divers")> _
        Public Property ScaleY() As Integer
            Get
                Return m_ScaleY
            End Get
            Set(ByVal Value As Integer)
                If Value < 0 Then
                    m_ScaleY = 1.0
                Else
                    m_ScaleY = Value
                End If
            End Set
        End Property
     
        Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
            MyBase.OnPaint(e)
            Dim gr As Graphics = e.Graphics
            gr.Clear(Color.White)
            'Ajoutez ici votre code de dessin personnalisé
            If (Me.bmp IsNot Nothing) Then
                Dim rect As Rectangle = New Rectangle(0, 0, Me.bmp.Width, Me.bmp.Height)
                gr.DrawImage(Me.bmp, rect)
            End If
     
        End Sub
     
        Private Sub CustomPanel_Scroll(ByVal sender As Object, ByVal e As System.Windows.Forms.ScrollEventArgs) Handles Me.Scroll
            Me.Invalidate()
        End Sub
     
        Private Sub CustomPanel_SizeChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.SizeChanged
            LoadCurrentMap()
            Me.Invalidate()
        End Sub
     
    End Class
    A dropper sur un form.....
    L'ennui dans ce procede est que tu encourt evidemment un "overhead" (surcharge) memoire car il y aura 2 bitmaps en memoire,celui du BufferedGraphics et le tiens.........

    Bon code...................

  3. #3
    Membre confirmé
    Homme Profil pro
    valves hydrauliques
    Inscrit en
    Septembre 2006
    Messages
    68
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : valves hydrauliques
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2006
    Messages : 68
    Par défaut Je ne suis pas sur de comprendre
    Bonsoir,

    et tout d'abord merci de ta reponse.
    Mais j'ai un peu du mal a comprendre, donc pour etre sur je vais essayer d'expliquer un peu mieux :

    Je dessine mon graph (ce qui est assez long a faire) dans le bitmap (ici BMP), qui est par exemple 1000 pixel de large, alors que le panel sur lequel j'affiche est seulement de 100 pixel de large.
    Puis (par exemple en fonction de la position de la scrollbar a chaque changement de celle-ci) je decoupe une partie du bitmap (de 100 pixel de large) le bitmap decoupé s'appele BMP1, et puis je le transfert sur le panel.

    Donc il faut dessiner dans un bitmap, j'ai trouvée

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
            ' creer bitmap complet et bitmap decoupé
            BMP = New Bitmap(Panel1.Width * ScaleX, Panel1.Height)
            BMP1 = New Bitmap(Panel1.Width, Panel1.Height)
     
            ' recuper le graphics de la surface de dessin complet
            GraphicsControl = Graphics.FromImage(BMP)
     
            ' dessiner
            GraphicsControl.FillRectangle(Brushes.Beige, 0, 0, Panel1.Width, Panel1.Height)
            For i = 0 To 1000 Step 10
                GraphicsControl.DrawLine(Pens.Black, 0, 0, i * 10, 1000)
            Next
    Puis decouper le bitmap, j'ai trouvée aussi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            ' decouper le bitmap dans le bitmap complet
            BMP1 = BMP.Clone(New Rectangle(10, 0, 100, 100), Imaging.PixelFormat.DontCare)
    mais comment transferé ce bitmap decoupé sur le panel, je ne sais pas ???

    Et est-ce que c'est la bonne approche ?

    Mais tu as compris le principe : je fais un grand dessin, que reste toujours en memoire, puis en fonction des scrollbars, on decoupe une partie image pour la mettre sur le panel.

    Ton code fait ça ?

    Merci de ton aide

    Armin

  4. #4
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut
    Bonjour armin...
    Non mon premier code dessine l'image à une taille indepenpendante de celle du controle,et on se contente de scroller le bmp (le faire defiler dans la fenetre du panel) avec des scrollbar...........

    Ce que tu viens de decrire c'est ce qu 'on appelle "zoomer un bmp"........

    Alors voici un usercontrol -sans scrollbar uniquement la souris - qui :
    - utilise comme le premier un BufferedGraphics et un Bitmap
    Mais il permet :
    - de panner
    - zoomer dans un bitmap qui reste centre
    - dont la taille peut etre personnalise (dans l'exemple code un bmp de largeur mini 80 sans depasser 900 et idem pour hauteur)....
    L'exemple est inspiree du controle d'image de BingMap de microsoft........
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
     
    System.Drawing.Drawing2D
     
    Public Class UserControlImage
        Private currentBmp As Bitmap
        Private GraphicsControl As Graphics
        Public Sub New()
     
            ' Cet appel est requis par le Concepteur Windows Form.
            InitializeComponent()
     
            ' Ajoutez une initialisation quelconque après l'appel InitializeComponent().
            LoadCurrentMap()
            CenterBmp = New Point(Me.ImageWidth / 2, Me.ImageHeight / 2)
     
     
            ' recuper le graphics de la surface de dessin
            GraphicsControl = Graphics.FromImage(currentBmp)
            renderBitmap(GraphicsControl, currentBmp)
        End Sub
        Private Sub LoadCurrentMap()
            currentBmp = New Bitmap(Me.Width, Me.Height)
            ' recuper le graphics de la surface de dessin
            GraphicsControl = Graphics.FromImage(currentBmp)
            renderBitmap(GraphicsControl, currentBmp)
     
            CenterBmp = New Point(Me.ImageWidth / 2, Me.ImageHeight / 2)
        End Sub
     
     
        Private Sub renderBitmap(ByVal GraphicsControl As Graphics, ByVal cachedCurrentMap As Bitmap)
            Dim ContextGraph As BufferedGraphicsContext = BufferedGraphicsManager.Current
            ContextGraph.MaximumBuffer = New Size(cachedCurrentMap.Width, cachedCurrentMap.Height)
     
            '--------  dimensioner le buffergraph  -------- 
            Dim BufferGraph As BufferedGraphics = ContextGraph.Allocate(GraphicsControl, New Rectangle(0, 0, cachedCurrentMap.Width, cachedCurrentMap.Height))
     
            '--------  effacer fond -------- 
            BufferGraph.Graphics.FillRectangle(Brushes.Beige, 0, 0, cachedCurrentMap.Width, cachedCurrentMap.Height)
            GraphicsControl.FillRectangle(Brushes.Beige, 0, 0, cachedCurrentMap.Width, cachedCurrentMap.Height)
     
            '--------  dessiner -------- 
            For i = 0 To 1000 Step 10
                BufferGraph.Graphics.DrawLine(Pens.Black, 0, 0, i * 10, 1000)
            Next
     
            '--------  envoyer dessin -------- 
            BufferGraph.Render()
            BufferGraph.Render(GraphicsControl)
            BufferGraph.Dispose()
     
            '-------- call to repaint --------
            Me.Invalidate()
        End Sub
     
     
     
     
        Private Sub UserControlImage_SizeChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.SizeChanged
            ' --------reload bmp --------
            Me.LoadCurrentMap()
     
            '-------- call to repaint --------
            Me.Invalidate()
        End Sub
     
        '---------------  Panning the bmp  ------------
     
        Private dragDifferential As Point = Point.Empty
        Private DownMouse As Boolean = False
        Private ptDown As Point = New Point(-1, -1)
        Private ptMove As Point = New Point(-1, -1)
        Private Sub UserControlImage_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseDown
            ptDown = Me.PointToClient(MousePosition)
            DownMouse = True
     
        End Sub
        Private Sub UserControlImage_Move(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Move
     
            '-------- ignore if mouse button is not down --------
            If (Not Me.DownMouse) Then Return
     
            ptMove = Me.PointToClient(MousePosition)
     
            '--------calculate change of mouse position --------
     
            Dim current As Point = Me.dragDifferential
            current.Offset((ptMove.X - ptDown.X), (ptMove.Y - ptDown.Y))
            '-------- update dragDifferential--------
            current = Me.dragDifferential
            ptDown = ptMove
     
     
            '-------- call to repaint --------
            Me.Invalidate()
        End Sub
        Private Sub UserControlImage_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseUp
            DownMouse = False
     
            '-------- update dragDifferential--------
            Dim ptUp As Point = Me.PointToClient(MousePosition)
            Me.dragDifferential = ptUp - ptDown
     
            '-------- update Center Bmp--------
            Me.LoadCurrentMap()
     
            ' --------reload bmp --------
            Me.CenterBmp = ptUp
     
     
        End Sub
     
        '--------------- Zooming the bmp  ------------
        '
        'Tracking the zoomDifferential
        Private zoomDifferential As Double = 1
        Private Sub UserControlImage_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseWheel
     
            If (e.Delta > 0) Then
                Me.zoomDifferential = 2 * Me.zoomDifferential
                Me.Zoom += Zoom
     
            ElseIf (e.Delta < 0) Then
                Me.zoomDifferential = Me.zoomDifferential / 2
                Me.Zoom -= Zoom
            End If
     
            ' --------reload bmp --------
            LoadCurrentMap()
     
            '-------- call to repaint --------
            Me.Invalidate()
     
        End Sub
        Private Sub UserControlImage_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
            If (Me.currentBmp Is Nothing) Then Return
            Dim gr As Graphics = e.Graphics
     
            '--------Centre des coord. au centre du bmp --------
            gr.TranslateTransform(Me.CenterBmp.X, Me.CenterBmp.Y)
     
            '--------is Moving the bmp --------
     
            If Not Me.dragDifferential.IsEmpty Then
                Dim diff As Point = dragDifferential - New Point(0, 0)
                e.Graphics.TranslateTransform(diff.X, diff.Y)
            End If
     
            '--------is Zooming the bmp --------
     
            If (Me.zoomDifferential <> 1) Then
                Dim zoom As Double = Me.zoomDifferential
                gr.ScaleTransform(zoom, zoom)
            End If
     
            '--------draw bmp centered (suite au centre decale) --------
            Dim rect As Rectangle = New Rectangle(-Me.CenterBmp.X, -Me.CenterBmp.Y, Me.ImageWidth, Me.ImageHeight)
            e.Graphics.DrawImage(Me.currentBmp, rect)
        End Sub
     
     
     
     
        ' ----------------- properties------------------ 
        Private m_centerBmp As Point = New Point(0, 0)
        Public Property CenterBmp() As Point
            Get
                Return m_centerBmp
            End Get
            Set(ByVal value As Point)
                m_centerBmp = value
            End Set
        End Property
        Private m_Zoom = 5
        Public Property Zoom() As Integer
            Get
                Return m_Zoom
            End Get
            Set(ByVal value As Integer)
                m_Zoom = Math.Min(Math.Max(value, 1), 21)
            End Set
        End Property
     
        ' -----------------ReadOnly properties------------------ 
        ' -----------------largeur max & hauteur max du bmp à toi de les
        '  ----------------suivant tes besoins -----------------
        Public ReadOnly Property ImageWidth() As Integer
            Get
                Return Math.Min(Math.Max(Me.currentBmp.Width, 80), 900)
            End Get
     
        End Property
        Public ReadOnly Property ImageHeight() As Integer
            Get
                Return Math.Min(Math.Max(Me.currentBmp.Height, 80), 900)
            End Get
     
        End Property
     
    End Class
    A dropper sur un form simplement.....
    Mais à propos connais-tu le roman et le film:
    Les Tribulations d'un Chinois en Chine est un roman de Jules Verne paru en 1879.....
    En 1965 Philippe de Broca a très librement adapté le roman : Les Tribulations d'un Chinois en Chine, avec Jean-Paul Belmondo.
    bon code................

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Graphic] Dessiner des hachures
    Par sylverspoon dans le forum 2D
    Réponses: 7
    Dernier message: 22/03/2006, 21h46
  2. OpenGL + GDI
    Par Twofy dans le forum OpenGL
    Réponses: 4
    Dernier message: 26/02/2004, 17h13
  3. [mfc][gdi] un tuto ?
    Par VitamineC dans le forum MFC
    Réponses: 8
    Dernier message: 06/02/2004, 22h51
  4. [MFC] libération des objets GDI's
    Par Kevgeii dans le forum MFC
    Réponses: 5
    Dernier message: 01/02/2004, 10h37
  5. Direct Graphics
    Par Blustuff dans le forum DirectX
    Réponses: 9
    Dernier message: 28/10/2002, 04h19

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo