Erreur générique s'est produite dans GDI+ (Enregistrement image) [Résolu]

Signaler
-
 Utilisateur anonyme -
Bonjour,
J'ai un problème avec mon code de capture d'écran, ce dernier fait une capture d'écran qui est stockée dans une picturebox, j'enregistre ensuite le contenu de cette picturebox au format BMP. Cependant, la première capture d'écran marche bien, l'image s'enregistre mais lorsque je tente d'en faire une deuxième, j'ai cette erreur : "Une erreur générique s'est produite dans GDI+".
J'ai fait quelques recherches et apparemment ça viendrait du fait que l'image est déjà utilisée, ouverte ou quelque chose comme ça.
Voici le code :
    Private Function TakeScreenShot() As Bitmap

        Dim screenSize As Size = New Size(My.Computer.Screen.Bounds.Width, My.Computer.Screen.Bounds.Height)

        Dim screenGrab As New Bitmap(My.Computer.Screen.Bounds.Width, My.Computer.Screen.Bounds.Height)

        Dim g As Graphics = Graphics.FromImage(screenGrab)

        g.CopyFromScreen(New Point(0, 0), New Point(0, 0), screenSize)
        PictureBox1.Image = screenGrab
        PictureBox1.Image.Save("C:\Capture.bmp") 'C'est ici que l'erreur apparait.
        PictureBox1.Image.Dispose() 'J'ai rajouté cette ligne pour essayer de vider le contenu.
        PictureBox1.Dispose() 'J'ai rajouté cette ligne pour essayer de vider le contenu.
        Return screenGrab

    End Function

Merci de votre aide !

10 réponses

Messages postés
378
Date d'inscription
samedi 22 septembre 2012
Statut
Membre
Dernière intervention
13 août 2017
14
Bonsoir FaonManager.

Le chemin d'accès de chacune des images sauvegardée n'est-il pas une chaîne de caractères ?

Cordialement.
1
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 152 internautes nous ont dit merci ce mois-ci

Messages postés
378
Date d'inscription
samedi 22 septembre 2012
Statut
Membre
Dernière intervention
13 août 2017
14
Bonjour FaonManager.

Quand vous écrivez
"C:\Capture.bmp"

vous ne faites que définir le chemin d'accès d'un fichier potentiel.
Quand vous écrivez
Image.Save("C:\Capture.bmp")

vous créez un fichier qui se trouve au chemin d'accès susnommé.
Et quand vous recommencez cette écriture, c'est comme si vous vouliez "écraser" le contenu du fichier. Pour ma part, je ne me suis jamais hasardé à faire une chose pareille. Mais c'est peut-être la cause de l'erreur.

Cordialement.
Messages postés
3258
Date d'inscription
jeudi 26 novembre 2009
Statut
Membre
Dernière intervention
3 décembre 2019
50
Salut

J'ai un problème avec mon code de capture d'écran, ce dernier fait une capture d'écran qui est stockée dans une picturebox

Je n'ai pas trop compris la logique
1 Est ce que la taille de ta picturebox est la meme que ton écran ?
si non pourquoi y stocker une image qui sera tronquée
ex si le screen size est width = 2000 height = 1000
l'image size de ta capture d'écran (screenGrab) est aussi de la meme taille width = 2000 height = 1000
tu écris
ton picturebox size est plus petit que ton écran donc si tu stock une image plus grande celle ci sera tronquée

2 à part ça je testé ton code je n'ai pas obtenu d'erreur
j'ai testé ainsi sur la form un picturebox et un bouton
  Private Function TakeScreenShot() As Bitmap
        Dim screenSize As Size = New Size(My.Computer.Screen.Bounds.Width, My.Computer.Screen.Bounds.Height)
        Dim screenGrab As New Bitmap(My.Computer.Screen.Bounds.Width, My.Computer.Screen.Bounds.Height)
        Dim g As Graphics = Graphics.FromImage(screenGrab)
        g.CopyFromScreen(New Point(0, 0), New Point(0, 0), screenSize)
        Pic1.Image = screenGrab
        Pic1.Image.Save("C:\Capture.bmp")
        Return screenGrab
    End Function


Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim B As Bitmap
        B = TakeScreenShot()
      
    End Sub


ou meme sans ton picturebox

Imports System.Drawing.Imaging
 Private Function TakeScreenShot() As Bitmap
        Dim screenSize As Size = New Size(My.Computer.Screen.Bounds.Width, My.Computer.Screen.Bounds.Height)
        Dim screenGrab As New Bitmap(My.Computer.Screen.Bounds.Width, My.Computer.Screen.Bounds.Height)
        Dim g As Graphics = Graphics.FromImage(screenGrab)
        g.CopyFromScreen(New Point(0, 0), New Point(0, 0), screenSize, CopyPixelOperation.SourceCopy)
        Return screenGrab
        'supprimer les disposes 
    End Function

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim B As Bitmap
        B = TakeScreenShot()
        B.Save("C:\Capture.bmp", ImageFormat.Bmp)
       
    End Sub


j'ai cliqué plusieurs fois de suite le bouton
Bonjour à vous deux,
shayw effectivement tes codes marchent si j'appelle la fonction à partir d'un bouton, cependant lorsque j'appelle la fonction en l'intégrant dans mon code, j'ai toujours le même problème.
C'est effectivement dû je pense à l'écrasement de l'ancienne image comme le dit Zermelo. J'ai donc pensé à une autre solution, enregistrer l'image et lui donner comme nom l'année, le mois, le jour, l'heure et les secondes. Il sera donc impossible que l'image ai deux fois le même nom. J'ai réussi à créer le code. Cependant, j'ai encore besoin de votre aide. Auriez vous une idée pour sauvegarder le nom de l'image sauvegardée dans une variable de type chaine de caractère ?
    Private Function TakeScreenShot() As Bitmap
        Dim screenSize As Size = New Size(My.Computer.Screen.Bounds.Width, My.Computer.Screen.Bounds.Height)
        Dim screenGrab As New Bitmap(My.Computer.Screen.Bounds.Width, My.Computer.Screen.Bounds.Height)
        Dim g As Graphics = Graphics.FromImage(screenGrab)
        g.CopyFromScreen(New Point(0, 0), New Point(0, 0), screenSize)
        PictureBox1.Image.Save("C:\Capture" & "." & Date.Now.Year & "." & Date.Now.Month & "." & Date.Now.Day & "." & Date.Now.Hour & "." & Date.Now.Minute & "." & Date.Now.Second & ".bmp")
        PictureBox1.Image.Dispose()
        PictureBox1.Dispose()
        Return screenGrab
    End Function

Merci.

Oui mais je ne peux pas l'utiliser par exemple après pour joindre l'image lors de l'envoi du mail. Avant, je mettais ce code ci :
mail.Attachments.Add(New Mail.Attachment("C:\Capture.bmp"))

Maintenant que le nom de l'image est à chaque fois différent, il faudrait que je le stock dans une variable.
Je n'ai aucune idée de comment faire car je ne peux pas par exemple déclarer une chaine de caractère juste après la sauvegarde de l'image car une seconde peut passer.
PictureBox1.Image.Save("C:\Capture" & "." & Date.Now.Year & "." & Date.Now.Month & "." & Date.Now.Day & "." & Date.Now.Hour & "." & Date.Now.Minute & "." & Date.Now.Second & ".bmp")
Dim NomImage As string = ("C:\Capture" & "." & Date.Now.Year & "." & Date.Now.Month & "." & Date.Now.Day & "." & Date.Now.Hour & "." & Date.Now.Minute & "." & Date.Now.Second & ".bmp")

Voilà, si tu arrives à m'aider ... !
Merci.
Messages postés
3258
Date d'inscription
jeudi 26 novembre 2009
Statut
Membre
Dernière intervention
3 décembre 2019
50
cependant lorsque j'appelle la fonction en l'intégrant dans mon code, j'ai toujours le même problème.

et comment ta fonction est appellée

http://support.microsoft.com/kb/915415/fr
http://www.developpez.net/forums/d129067/dotnet/developpement-windows/windows-forms/csharp-erreur-gdip/

J'appelle la fonction avec le même code que tu utilises pour le bouton.

En essayant d'écrire le nom de l'image sauvegardé dans un fichier texte, je me suis rendu compte que ça fonctionne, je contourne donc le problème de GDI. Cependant, mon ordinateur étant assez puissant, est-ce que si l'utilisateur de mon programme possède une vieille machine, cette dernière ne risque pas de mettre plus d'une seconde à exécuter ce code :
        Dim StreamWriter As New StreamWriter("C:\Date.txt")
        screenGrab.Save("C:\Capture" & "." & Date.Now.Year & "." & Date.Now.Month & "." & Date.Now.Day & "." & Date.Now.Hour & "." & Date.Now.Minute & "." & Date.Now.Second & ".bmp")
        StreamWriter.Write("C:\Capture" & "." & Date.Now.Year & "." & Date.Now.Month & "." & Date.Now.Day & "." & Date.Now.Hour & "." & Date.Now.Minute & "." & Date.Now.Second & ".bmp")
        StreamWriter.Close()


A moins qu'il y ait une solution plus propre ?
Merci.
Messages postés
378
Date d'inscription
samedi 22 septembre 2012
Statut
Membre
Dernière intervention
13 août 2017
14
Bonjour FaonManager.

Je vous suggère d'importer les classes System.DateTime et System.String, et d'utiliser la fonction suivante,

Private Function Chemin() As String
        Return "C:\Capture" & "." & Now.ToString.Replace("/", ".").Replace(" ", ".").Replace(":", ".") & ".bmp"
    End Function


Cordialement.

Très bien, j'ai finalement gardé ma solution, on verra par la suite si ça pose des problèmes, merci à tous !