Conversion d'un graphique de PictureBox a une image [Résolu]

Signaler
-
Messages postés
2427
Date d'inscription
samedi 11 janvier 2014
Statut
Contributeur
Dernière intervention
6 mai 2021
-
Bonjour,
Je suis un novice dans le VB.NET je me heurte a un problème que je n'arrive pas a résoudre.
Je crée une PictureBox nommée :
PictureBoxgra

Pour utiliser divers outils de dessins je fait dans mon form load:
Graph = PictureBoxgra.CreateGraphics()

avec Graph déclarer en globale de cette manière:
Dim Graph As Graphics

jusque la tout va bien !(enfin j'espère )
je dessine divers chose qui s'affiche de la manière souhaiter.

cependant j'aimerai pouvoir enregistrer une image, non pas de la picturebox.
Mes bien de Graph qui contient les divers dessins...
j'ai beaucoup chercher j'ai vu quelque forum traitant du problème mes dans un contexte trait pousser qui me dépasse.

J'espère que mon poste ne dérangera pas, je suis désoler si le problème peut sembler simple.
Je suis évidement preneur de toute avis
Merci d'avance

12 réponses

Messages postés
15961
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
19 mai 2021
547
Bonjour

LePictureBox.Image.Save("C:\temp\export.jpg",ImageFormat.Jpeg)

Messages postés
2427
Date d'inscription
samedi 11 janvier 2014
Statut
Contributeur
Dernière intervention
6 mai 2021
137
Bonjour
Il faut passer par un bitmap .
Code exemple
' création du bitmap de la Picturebox
Dim Mybitmap as Bitmap = New Bitmap(PictureBoxgra.Width, PictureBoxgra.Height)
' outil graphique
Dim g As Graphics = Graphics.FromImage(MyBitmap)
' vos routines de dessin avec g as Graphics

' on crée l'image de la Picturebox
PictureBoxgra.Image = MyBitmap
' on sauvegarde dans un fichier
Mybitmap.Save("C:\temp\export.jpg",ImageFormat.Jpeg)


un exemple sorti d'un des mes codes (CaseJeu est une classe qui hérite de PictureBox)
''' <summary>
    ''' Affiche une lettre sur le plateau de jeu
    ''' </summary>
    ''' <param name="CaseJeu"></param>
    ''' <param name="Lettre"></param>
    ''' <param name="Valeur"></param>
    ''' <param name="CouleurFond"></param>
    ''' <param name="CouleurOrigine"></param>
    Private Sub AfficheLettrePlateau(CaseJeu As ClassCaseJeu, Lettre As String, Valeur As Integer, CouleurFond As Color, CouleurOrigine As Color) Handles Jeu.AfficheLettrePlateau, Deplacement.AfficheLettrePlateau

        ' Affiche la lettre dans le contrôle PictureBox avec rappel de la couleur d'origine de la case du plateau
        ' Si la case a un pouvoir multiplicateur ( Lettre ou Mot ) on affiche la couleur d'origine
        ' Les lettres remplaçant le joker sont de couleur rouge alors que les autres sont noires
        Dim TaillePolice As Integer = If(Lettre = "*", 22, 20)
        Dim MyBitmap As Bitmap = New Bitmap(35, 35)
        Dim g As Graphics = Graphics.FromImage(MyBitmap)
        With g
            .Clear(CouleurFond)
            .DrawString(Lettre, New Font("Consolas", TaillePolice, FontStyle.Bold, GraphicsUnit.Point), If(Valeur <> 0, Brushes.Black, Brushes.Red), 0, 1)
            .DrawString(Valeur.ToString, New Font("Microsoft Serif", 7, FontStyle.Bold, GraphicsUnit.Point), Brushes.Black, 18, 22)
            If CouleurOrigine <> Color.GreenYellow Then
                .FillEllipse(New SolidBrush(CouleurOrigine), New Rectangle(22, 0, 10, 10))
            End If
        End With
        CaseJeu.Image = MyBitmap

    End Sub

Bonjour,
Je teste immédiatement merci!
Messages postés
2427
Date d'inscription
samedi 11 janvier 2014
Statut
Contributeur
Dernière intervention
6 mai 2021
137
Bonjour
C'est quoi ces fonctions ?
temp = ENTREMELLE(str:=fonctionavecvariable) 'procedure de calcule 
temp2 = ENTREMELLE(str:=fonctionavecvariable2) 'procedure de calcule 

Bonjour,
c'est une fonction qui retourne un résultat a partir d'un calcul écrit en string .
Messages postés
2427
Date d'inscription
samedi 11 janvier 2014
Statut
Contributeur
Dernière intervention
6 mai 2021
137
Le paramètre de ENTREMELLE est bizarre . On dirait une écriture en C ou C++ . Et cela calcule quoi ?
Tu peux nous mettre le code des boutons 1 et 2 .
Si je comprends bien tu dois sélectionner un type de courbe et la dessiner avec le bouton 1.
Le bouton 2 te sert à enregistrer l'image de le Picturebox .
Messages postés
2427
Date d'inscription
samedi 11 janvier 2014
Statut
Contributeur
Dernière intervention
6 mai 2021
137
Bonjour
1) Ce n'est pas ainsi que l'on fournit des paramètres en VB Net pour une Sub ou une Function
Private Sub Buttoncourbe_Click(sender As Object, e As EventArgs) Handles Buttoncourbe.Click
        dessins(str:=TextBoxfonction.Text, couleur:=Color.Blue)
End Sub

On fait ainsi
Private Sub Buttoncourbe_Click(sender As Object, e As EventArgs) Handles Buttoncourbe.Click
        Dessins(TextBoxfonction.Text, Color.Blue)
End Sub


Ensuite pour la Sub elle-même
Private Sub Dessins(str As String, couleur As Color)

End sub


2) Dans la Sub Dessins vous n'avez pas créé le bitmap ni l'objet graphique .
Je vous ai bien dit de les créer tous les deux avant de vous servir de cet objet graphique pour dessiner.
une fois le dessin fini vous pourrez l'enregistrer

3) il faut d'abord mettre en variable Private pour toute la Form le bitmap ainsi que l'objet graphique .
Private Mybitmap As Bitmap
Private Graph As Graphics


ensuite dans la sub Dessins les 2 premières lignes de code doivent être
Mybitmap = New Bitmap(PictureBoxgra.Width, PictureBoxgra.Height)
Graph = Graphics.FromImage(Mybitmap)


et pour le bouton 2 pour enregistrer
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        
        PictureBoxgra.Image = Mybitmap
        Mybitmap.Save("D:\nomfichier.jpg", ImageFormat.Jpeg)

    End Sub




Messages postés
2427
Date d'inscription
samedi 11 janvier 2014
Statut
Contributeur
Dernière intervention
6 mai 2021
137
Le Graph passe par la Sub Dessins
supprimez ces 3 lignes dans le Form1.Load pour les mettre dans la sub Dessins après les 2 lignes d'initialisation du bitmap et de l'objet graphique .
Les premières lignes de la Sub Dessins doivent être celles-ci
Mybitmap = New Bitmap(PictureBoxgra.Width, PictureBoxgra.Height)
Graph = Graphics.FromImage(Mybitmap)
With Graph
      .PageUnit = GraphicsUnit.Millimeter 
      .ScaleTransform(EchelleX, EchelleY)
      .TranslateTransform(OrigineX, OrigineY)
End with

Le With ........ End With permet de ne pas réécrire à chaque fois Graph

supprimer les lignes dans le Form1.Load
 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        EchelleX = 10
        EchelleY = -10
        OrigineX = 3.75
        OrigineY = -4
        Graph = PictureBoxgra.CreateGraphics() ' à supprimer
        Graph.PageUnit = GraphicsUnit.Millimeter ' à supprimer
        Graph.ScaleTransform(EchelleX, EchelleY) ' à supprimer
        Graph.TranslateTransform(OrigineX, OrigineY) ' à supprimer


    End Sub

Messages postés
2427
Date d'inscription
samedi 11 janvier 2014
Statut
Contributeur
Dernière intervention
6 mai 2021
137
De rien ! On est là pour cela !
Je vous remercie de votre proposition, je l'est déjà malheureusement tester toujours la même erreur qui viens pourtant tout semble en ordre...

System.NullReferenceException : 'La référence d'objet n'est pas définie à une instance d'un objet.'

System.Windows.Forms.PictureBox.Image.get retournée Nothing.
Je dessine avec le bouton 1 et tente d'enregistrer avec le code fournit dans le bouton 2,
je n'est pas d'erreur mes l'image récupérer est totalement noir.
l'idée est de créer l'image a la fin de cette procédure :
    
Private Sub dessins(str As String, couleur As Color)
        Dim pas As Single = 0.5 ' pas de déplacement dans fonction 
        Dim fonctionavecvariable As String 'image de fonction a l'instant t
        Dim fonctionavecvariable2 As String 'image de fonction a l'instant t+1
        Dim fonctionabege As String 'stock la fonction rentrer 

        'abreviation des objet math
        fonctionabege = str
        fonctionabege = Replace(fonctionabege, "arccos", "C")
        fonctionabege = Replace(fonctionabege, "arcsin", "S")
        fonctionabege = Replace(fonctionabege, "arctan", "N")
        fonctionabege = Replace(fonctionabege, "cos", "c")
        fonctionabege = Replace(fonctionabege, "sin", "s")
        fonctionabege = Replace(fonctionabege, "tan", "n")
        fonctionabege = Replace(fonctionabege, "exp", "e")
        fonctionabege = Replace(fonctionabege, "log", "g")
        fonctionabege = Replace(fonctionabege, "racine", "r")

        Dim temp As String 'image de fonction a l'instant1< t <1
        Dim temp2 As String 'image de fonction a l'instant1< t+1 <1
        Dim numtemp As Single 'dif des dimage de la fonction  

        For t = -302 To 302 Step pas
            If t < 1 And t > -1 Then

            Else
                numtemp = t + pas

                fonctionavecvariable = Replace(fonctionabege, "t", "(" & t & ")",) 'retourne calcule a faire 
                fonctionavecvariable2 = Replace(fonctionabege, "t", "(" & numtemp & ")",) 'retourne calcule a faire 

                temp = ENTREMELLE(str:=fonctionavecvariable) 'procedure de calcule 
                temp2 = ENTREMELLE(str:=fonctionavecvariable2) 'procedure de calcule 
                If temp = "Oula" Or temp2 = "Oula" Then
                    'pas de traitement operation infesable 
                Else

                    'liason des images pour former une courbe 
                    Graph.DrawLine(New Pen(couleur, 0.08F), CSng(t), CSng(temp), CSng(numtemp), CSng(temp2))
                End If
            End If
        Next

        'identique mes plus précis pour -1<t<1 
        pas = 0.005
        For t = -1 To 1 Step pas

            numtemp = t + pas
            fonctionavecvariable = Replace(fonctionabege, "t", "(" & t & ")",)

            temp = ENTREMELLE(str:=fonctionavecvariable)

            If temp = "Oula" Then

            Else

                Graph.DrawLine(New Pen(couleur, 0.08F), CSng(t), CSng(temp), CSng(t + pas), CSng(temp + 0.05))
            End If

        Next

    End Sub
Dans le bouton 1 :

Private Sub Buttoncourbe_Click(sender As Object, e As EventArgs) Handles Buttoncourbe.Click
        dessins(str:=TextBoxfonction.Text, couleur:=Color.Blue)
End Sub


avec le bouton 1 qui est Buttoncourbe je récupère une fonction qui est écrit par l'utilisateur dans : TextBoxfonction.
J'appelle la procédure de dessins qui va changer la variable(t) de la fonction en un nombre ENTREMELLE elle fait le calcul de la fonction avec se nombre .(en théorie elle résous tout les calculs de base )et donc elle renvoie l'image puis fait de même avec le même un nombre incrémenter. Je récupère deux image dont je me sers pour tracer un trait. Le tout est dans une boucle donc je trace la fonction de -302 a 302. sur le graph de ma picturebox .

j'aimerait ensuite enregistrer avec le bouton 2 une image du graph
dedans il le code vous m'avez fournit
.
 Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        Dim Mybitmap As Bitmap = New Bitmap(PictureBoxgra.Width, PictureBoxgra.Height)
        Dim Graph As Graphics = Graphics.FromImage(Mybitmap)
        PictureBoxgra.Image = Mybitmap
        Mybitmap.Save("D:\export.jpg", ImageFormat.Jpeg)

    End Sub
Bonjour,
on direr que le graph ne passe plus part mon form load
  Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        EchelleX = 10
        EchelleY = -10
        OrigineX = 3.75
        OrigineY = -4
        Graph = PictureBoxgra.CreateGraphics()
        Graph.PageUnit = GraphicsUnit.Millimeter
        Graph.ScaleTransform(EchelleX, EchelleY)
        Graph.TranslateTransform(OrigineX, OrigineY)


    End Sub

Ducoup le tracer n'a plus rien a voir cependant se qui est afficher est enregistrer correctement.
Merci beaucoup pour le temps passer,
tout fonctionne parfaitement !
Une excellente fin de journée a vous .