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

CLeBeR_FR 301 Messages postés mercredi 22 septembre 2010Date d'inscription 27 février 2018 Dernière intervention - 4 août 2013 à 23:24 - Dernière réponse : CLeBeR_FR 301 Messages postés mercredi 22 septembre 2010Date d'inscription 27 février 2018 Dernière intervention
- 6 août 2013 à 12:04
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 !
Afficher la suite 

10 réponses

Zermelo 378 Messages postés samedi 22 septembre 2012Date d'inscription 13 août 2017 Dernière intervention - 5 août 2013 à 20:12
+1
Utile
Bonsoir FaonManager.

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

Cordialement.
Cette réponse vous a-t-elle aidé ?  
Zermelo 378 Messages postés samedi 22 septembre 2012Date d'inscription 13 août 2017 Dernière intervention - 5 août 2013 à 09:32
0
Utile
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.
cs_ShayW 3238 Messages postés jeudi 26 novembre 2009Date d'inscription 14 mars 2018 Dernière intervention - 5 août 2013 à 13:28
0
Utile
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
CLeBeR_FR 301 Messages postés mercredi 22 septembre 2010Date d'inscription 27 février 2018 Dernière intervention - Modifié par FaonManager le 5/08/2013 à 20:31
0
Utile
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.
CLeBeR_FR 301 Messages postés mercredi 22 septembre 2010Date d'inscription 27 février 2018 Dernière intervention - 5 août 2013 à 20:28
0
Utile
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.
cs_ShayW 3238 Messages postés jeudi 26 novembre 2009Date d'inscription 14 mars 2018 Dernière intervention - 5 août 2013 à 22:58
0
Utile
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/
CLeBeR_FR 301 Messages postés mercredi 22 septembre 2010Date d'inscription 27 février 2018 Dernière intervention - 5 août 2013 à 23:16
0
Utile
J'appelle la fonction avec le même code que tu utilises pour le bouton.
CLeBeR_FR 301 Messages postés mercredi 22 septembre 2010Date d'inscription 27 février 2018 Dernière intervention - 5 août 2013 à 23:30
0
Utile
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.
Zermelo 378 Messages postés samedi 22 septembre 2012Date d'inscription 13 août 2017 Dernière intervention - 6 août 2013 à 10:52
0
Utile
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.
CLeBeR_FR 301 Messages postés mercredi 22 septembre 2010Date d'inscription 27 février 2018 Dernière intervention - 6 août 2013 à 12:04
0
Utile
Très bien, j'ai finalement gardé ma solution, on verra par la suite si ça pose des problèmes, merci à tous !

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.