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 :

Problème avec Dispose() sur picturebox


Sujet :

VB.NET

  1. #1
    Membre régulier
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    117
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 117
    Points : 72
    Points
    72
    Par défaut Problème avec Dispose() sur picturebox
    Bonjour, je suis en train de faire une transparence sur une image via un code que j'ai trouvé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
            Dim newBmp = New Bitmap(PictureBox1.Image.Width, PictureBox1.Image.Height)
            Dim graf = Graphics.FromImage(newBmp)
            Dim ColMatrix As New ColorMatrix
            Dim imgAttribute As ImageAttributes = New ImageAttributes()
            ColMatrix.Matrix33 = 0.3
     
            imgAttribute.SetColorMatrix(ColMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap)
            graf.DrawImage(PictureBox1.Image, New Rectangle(0, 0, newBmp.Width, newBmp.Height), 0, 0, PictureBox1.Image.Width, PictureBox1.Image.Height, GraphicsUnit.Pixel, imgAttribute)
     
            PictureBox2.Image = newBmp
            graf.Dispose()
    Que j'insert dans un bouton, le code fonctionne bien.
    Le problème et que à chaque fois que l'on clique sur le bouton le

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dim newBmp = New Bitmap(PictureBox1.Image.Width, PictureBox1.Image.Height)
    Insert un bitmap dans la ram et donc à 500 clique on a plus de mémoire ram.

    Pour vider la ram j'ai pensé à faire un newBmp.Dispose() après PictureBox2.Image = newBmp mais le picturebox2 n'a pas le temps d'inserer l'image à cause du dispose et sa me retourne donc une erreur.

    Apparemment Vb.net n'attend pas que l'instruction PictureBox2.Image = newBmp se termine pour passer à newBmp.Dispose()

    Une personne à une idée du problème ? Merci

  2. #2
    Modérateur

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 722
    Points : 5 100
    Points
    5 100
    Par défaut
    Bonjour,

    En fait tu libère la ressource, ton objet bitmap. PictureBox2.Image et newBmp pointe sur le même objet.

    Fait,
    Cela ne concernera que newBmp.

    A+, Hervé.

  3. #3
    Membre régulier
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    117
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 117
    Points : 72
    Points
    72
    Par défaut
    Salut, j'ai déjà tenté le nothing sur le newBmp et sa ne libère pas la Ram. Avec le code sur un timer à 100, même avec un nothing sur le newBmp au bout de 2 secondes plus de 400 Mo d'utilisés.

    Pour ce qui est "qu'il pointe du même objet", ce qui est étonnant c'est que si je lance le dispose dans un nouveau thread qui patiente, là je n'est pas d'erreur, étonnant.

  4. #4
    Membre expérimenté
    Homme Profil pro
    Développeur .Net / Delphi
    Inscrit en
    Juillet 2002
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Développeur .Net / Delphi
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2002
    Messages : 738
    Points : 1 745
    Points
    1 745
    Par défaut
    Bonjour,

    A mon avis : Tu définis newBmp en dehors de ta procedure et à chaque clique sur le bouton, tu testes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    If newBmp IsNot Nothing Then
      newBmp.dispose
      newBmp = Nothing
    End If
    newBmp = New Bitmap(PictureBox1.Image.Width, PictureBox1.Image.Height)
    ...
    ça devrait résoudre le problème.
    eb.

  5. #5
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 177
    Points : 25 125
    Points
    25 125
    Par défaut
    Citation Envoyé par Guyome41 Voir le message
    Apparemment Vb.net n'attend pas que l'instruction PictureBox2.Image = newBmp se termine pour passer à newBmp.Dispose()
    ce n'est pas ca qui se passe
    les instructions sont exécutées les unes après les autres
    c'est juste que .Dispose détruit un objet géré par l'OS (c'est le cas des images) et libère sa mémoire
    donc si tu donnes l'image au picturebox et que tu la détruit il ne peut pas l'afficher (l'affichage n'est pas fait qu'à un l'instant T, l'interface est rafraichit assez souvent, et donc le picturebox a besoin de l'image)

    pour éviter que la ram monte, il ne faut pas détruire le bitmap que tu viens de créer, mais celui que tu utilisais avant et que tu n'utilises plus, comme le montre ebastien, qui peut aussi se code de la manière suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    If PictureBox2.Image IsNot Nothing Then
      PictureBox2.Image.Dispose 
    End If
    PictureBox2.Image = newbmp
    une variable est mise à nothing en sortie de portée (sur un dim dans une sub, la variable est mise à nothing à la sortie de la sub)
    par contre le contenu est détruit à postériori et aléatoirement dans le temps
    Dispose force le vidage de la ram des objets gérés par l'OS

  6. #6
    Membre régulier
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    117
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 117
    Points : 72
    Points
    72
    Par défaut
    Merci pour vos réponses, c'est vrai que Windows rafraîchi l'affichage et je n'y avais pas pensé malgré avoir lu quelque tutos sur le sujet.

    Bref, sa fonctionne bien j'ai plus qu'a l'adapter sur mon code. Par contre il y a un truc que je ne comprend pas :

    Quand tu fait un dispose() puis tu recharge l'image PictureBox2.Image = newbmp il y a bien un lapse de temps ou la picturebox n'a plus d'image alors pourquoi sa ne plante pas ?

  7. #7
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 177
    Points : 25 125
    Points
    25 125
    Par défaut
    il y a plusieurs raisons pour qu'un controle se redessine, l'une d'entre elles est le changement de valeur d'une propriété (ou d'instance dans le cas d'image)
    quand on fait .dispose sur l'image, la propriété ne change pas, le picturebox n'est pas averti
    par contre en mettant newbmp là le picturebox sait qu'il doit se redessiner, mais sont image existe
    pendant l'exécution de ta sub, il ne peut pas y avoit un event qui s'exécute entre temps, donc même si windows demande le rafraichissement du controle, ca ne sera fait qu'après la sortie de ta sub

  8. #8
    Membre régulier
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    117
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 117
    Points : 72
    Points
    72
    Par défaut
    Merci.

  9. #9
    Modérateur

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 722
    Points : 5 100
    Points
    5 100
    Par défaut
    Pour information,
    Citation Envoyé par Guyome41 Voir le message
    Salut, j'ai déjà tenté le nothing sur le newBmp et sa ne libère pas la Ram. Avec le code sur un timer à 100, même avec un nothing sur le newBmp au bout de 2 secondes plus de 400 Mo d'utilisés.
    ...
    Effectivement nothing ne libère pas la mémoire occupé par l'objet, chaque objet créé occupera donc une place supplémentaire, mais à un moment le système déclenchera le Garbage Collector qui nettoiera la mémoire des objets qui ne sont plus référencés.
    (c'est pour cela que je te disais de mettre simplement ta variable newBmp sur nothing pour ne pas risquer de modifier PictureBox2.Image à travers newBmp et laisser le GC faire le ménage lorsque le besoin se fera sentir)

    C'est ce que t'indique Pol63 dans le post 5
    Citation Envoyé par Pol63 Voir le message
    une variable est mise à nothing en sortie de portée (sur un dim dans une sub, la variable est mise à nothing à la sortie de la sub)
    par contre le contenu est détruit à postériori et aléatoirement dans le temps
    A+, Hervé.

  10. #10
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 177
    Points : 25 125
    Points
    25 125
    Par défaut
    le gc c'est bien, mais dans certains cas dispose est indispensable (sous peine de OutOfMemoryException qui plante tout, même catchée)
    et dans tous les cas il est recommandé

  11. #11
    Membre régulier
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    117
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 117
    Points : 72
    Points
    72
    Par défaut
    Oui en laissant tourné l'appli j'avais le droit à un "Mémoire insuffisante". Quand j'ai vue qu'a 3, 4 secondes l'appli bouffé toute ma ram je cherché une solution.

    Enfin, maintenant une chose est sûr c'est que je vais faire plus attention à mes variables pour libérer au max la ram sur mes prochaines appli

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

Discussions similaires

  1. [XI] problème avec groupe sur un champ trié par origine ?
    Par kikidrome dans le forum SAP Crystal Reports
    Réponses: 6
    Dernier message: 11/04/2007, 15h31
  2. problème avec select sur onchange
    Par Kerod dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 01/12/2005, 14h05
  3. Problèmes avec INTERSECT sur MYSQL
    Par zarbydigital dans le forum Requêtes
    Réponses: 1
    Dernier message: 27/09/2005, 13h18
  4. Problème avec OnDrawColumnCell sur un DBGrid
    Par n1portki dans le forum Composants VCL
    Réponses: 3
    Dernier message: 23/09/2005, 04h18
  5. Problème avec RDTSC sur K6-III
    Par le mage tophinus dans le forum x86 32-bits / 64-bits
    Réponses: 17
    Dernier message: 30/09/2003, 09h43

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