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

Lazarus Pascal Discussion :

Problème de perte de mémoire avec l'instruction "Resample" de la bibliothèque TBGRABitmap [Lazarus]


Sujet :

Lazarus Pascal

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 79
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 122
    Par défaut Problème de perte de mémoire avec l'instruction "Resample" de la bibliothèque TBGRABitmap
    Bonjour à toutes et à tous,

    Je suis en train de réaliser une application GPS dont l'affichage est géré à l'aide de la bibliothèque TBGRABitmap. J'obtiens un affichage relativement fluide, sur le déplacement, la rotation et le ré-échantillonnage de mon image, sauf qu'à chaque rafraichissement de mon image (toutes les secondes), je perds de l'ordre de 1 ko de mémoire, ce qui fait qu'au bout de quelques centaines de secondes, l'application plante !

    Dans la procédure suivante que j'emploie pour afficher mon image, j'ai réussi à trouver le coupable : c'est la fonction "Resample". Est-ce moi qui ne l'utilise pas correctement ou bien est-ce lié à cette fonction ?

    Merci pour vos informations.


    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
    procedure TAffCarte.PaintBoxPaint(Sender: TObject);
    // *** la PaintBox est repainte ***
    var
      LBmp: TBGRABitmap;
    begin
      LBmp := TBGRABitmap.Create(PaintBox.Width, PaintBox.Height, BGRAWhite);
      try
        LBmp.PutImageAngle(Dec0.X-Depl.X, Dec0.Y-Depl.Y, bmpCarte, tckbAngle.Position,
        AffXdiv2-(Dec0.X-Depl.X), AffYdiv2-(Dec0.Y-Depl.Y),
        $FF, DecalApresRot, False); // Déplacement et rotation
        kZoom:= tckbResample.Position / 100;
        HG.X:= Round((1-kZoom)*(AffXdiv2));
        HG.Y:= Round((1-kZoom)*(AffYdiv2));
        LBmp := LBmp.Resample(Round(Lbmp.Width * kZoom), Round(LBmp.Height* kZoom), rmSimpleStretch) as TBGRABitmap; // Zoom
        LBmp.Draw(PaintBox.Canvas, HG.X, HG.Y, False); // Trace la carte avec ses déplacements, zoom et rotation
        LBmp.Free;
      except
        LBmp.Free;
      end;
      Mem:= GetHeapStatus; // A chaque tour, je perd environ 1 ko de mémoire
      Edit5.Text:= IntToStr(Mem.TotalFree);
    end;
    Cordialement.

    Pierre

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour Pierre,

    sans aucune certitude, un FreeAndNil(LBmp) au lieu d'un LBmp.free change-t-il quelque chose au problème ?

    Cordialement. Gilles

  3. #3
    Membre émérite
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 79
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 122
    Par défaut
    Citation Envoyé par Selzig Voir le message
    ... sans aucune certitude, un FreeAndNil(LBmp) au lieu d'un LBmp.free change-t-il quelque chose au problème ? ...
    J'avais déjà essayé, et malheureusement, cela ne change rien.

    Cordialement.

    Pierre

  4. #4
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 142
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 142
    Par défaut
    Yop !

    Pas de solution au plantage, d'autant plus que 1 ko de conso ce n'est pas la mer à boire, en tablant sur un millier de passages (supérieur donc à tes quelques centaines) ça ne ferait jamais qu'un méga, tu devrais avoir de la marge, à notre époque.

    Par contre, un objet qui doit être créé toutes les secondes pour être un peu utilisé puis libéré et on recommence, je trouve ça un peu idiot.

    Perso, sur un coup pareil, je fais sa création dans le FormCreate et sa libération dans le FormClose, et à chaque tour de boucle, puisqu'il s'agit d'un bitmap (avec une déclaration globale), je commence par un .FreeImage.

    À voir.

  5. #5
    Membre Expert
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Billets dans le blog
    2
    Par défaut
    Salut BGRABitmap est un peu bizarre des fois, ce 1ko ????
    en regardant le code de bgra derriere la fonction resample on trouve dans l'unité BGRAResample

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function SimpleStretch(bmp: TBGRACustomBitmap;
      newWidth, newHeight: integer): TBGRACustomBitmap;
    begin
      if (NewWidth = bmp.Width) and (NewHeight = bmp.Height) then
      begin
        Result := bmp.Duplicate;
        exit;
      end;
      Result := bmp.NewBitmap(NewWidth, NewHeight);
      StretchPutImage(bmp, newWidth,newHeight, result, 0,0, dmSet, 255);
    end;
    Je pense que les adresse des bitmaps ne sont pas mis à "nil" correctement. Bien vue Gilles le FreeAndNil mais est sans effet ici

    Dans la fonction ci-dessus le result est assigné avec un nouveau Bitmap, puis le result qui est la destination et Bmp la source dans StretchPutImage,
    On dirait plus une erreur d'assignation "d'adresse" ou de buffer non libérer/pas réallouer correctement a l'assignation . Ici c'est comme le serpent qui se mort la queue si voyez ou je veux en venir.

    Si Circular passe par là, il pourra éclaircir ce mystère.

    Neanmoins pour ma part, Je ne sais pas trop si c'est la meilleur solution, mais je ferai quelques chose comme ça pour tester :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    function SimpleStretch(bmp: TBGRACustomBitmap; newWidth, newHeight: integer): TBGRACustomBitmap;
    Var
    TmpBmp : TBGRACustomBitmap;
    begin
      if (NewWidth = bmp.Width) and (NewHeight = bmp.Height) then
      begin
        Result := bmp; //.Duplicate;
        exit;
      end;
      TmpBmp := Bmp.Duplicate;//ou juste  TmpBmp := Bmp; Duplicate vraiment nécessaire ?????
      Result := bmp.NewBitmap(NewWidth, NewHeight);
      StretchPutImage(TmpBmp, newWidth,newHeight, result, 0,0, dmSet, 255);
      FreeAndNil(TmpBmp);
    end;
    A+
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  6. #6
    Membre émérite
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 79
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 122
    Par défaut
    Merci Jipété pour ces propositions.

    Citation Envoyé par Jipété Voir le message
    ... Pas de solution au plantage, d'autant plus que 1 ko de conso ce n'est pas la mer à boire, en tablant sur un millier de passages (supérieur donc à tes quelques centaines) ça ne ferait jamais qu'un méga, tu devrais avoir de la marge, à notre époque. ...
    Sur mon PC, le "tas" ne représente qu'1 Mo (je ne te raconte pas sur mon Raspberry ) soit au bout de 1000 secondes, ça plante : durée un peu courte pour un GPS que je souhaite voir fonctionner plusieurs heures.

    Citation Envoyé par Jipété Voir le message
    ... Perso, sur un coup pareil, je fais sa création dans le FormCreate et sa libération dans le FormClose, ...
    Ça n'a rien changé au fonctionnement.

    Citation Envoyé par Jipété Voir le message
    ... puisqu'il s'agit d'un bitmap (avec une déclaration globale), je commence par un .FreeImage ... .
    L'instruction .FreeImage n'existe pas pour la classe TBGRAImage .

    Le problème semble interne à l'instruction .Resample.

    Cordialement.

    Pierre

  7. #7
    Membre émérite
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 79
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 122
    Par défaut
    @ BeanzMaster :

    Dans mes essais , j'avais remarqué que dans la fonction "SimpleStretch" de l'unité "BGRAResample", la fonction "Duplicate" créait une fuite de mémoire et j'avais supprimé cette fonction. Pour un non redimensionnement, je n'avais plus de fuite de mémoire ; mais je la retrouvais pour un redimensionnement .

    Dans la fonction "SimpleStretch" que tu me proposes, il faut aussi supprimer cette fonction dans le cas de redimensionnement et là, tout fonctionne bien, plus de fuite de mémoire .

    La fonction proposée devient donc :

    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
    function SimpleStretch(bmp: TBGRACustomBitmap; newWidth, newHeight: integer): TBGRACustomBitmap;
    (* Cette fonction remplace celle de l'unité BGRAResample où la fonction "Duplicate"
       crée une fuite de mémoire *)
    var
      TmpBmp: TBGRACustomBitmap;
    begin
      if (NewWidth = bmp.Width) and (NewHeight = bmp.Height) then
      begin
        Result := bmp;
        exit;
      end;
      TmpBmp := Bmp;
      Result := bmp.NewBitmap(NewWidth, NewHeight);
      StretchPutImage(TmpBmp, newWidth, newHeight, Result, 0, 0, dmSet, $FF);
      FreeAndNil(TmpBmp);
    end;
    Pour l'utiliser, il faut toutefois ajouter l'unité BGRAResample et faire un transtypage du résultat, par exemple dans mon cas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        LBmp:= TBGRABitmap(SimpleStretch(LBmp, Round(1024*kZoom), Round(600*kZoom)));
    Un grand merci.

    Cordialement.

    Pierre

  8. #8
    Membre Expert
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par ChPr Voir le message
    @ BeanzMaster :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        LBmp:= TBGRABitmap(SimpleStretch(LBmp, Round(1024*kZoom), Round(600*kZoom)));
    Un grand merci.

    Cordialement.

    Pierre
    Salut

    Cela me conforte dans mes dires, BGRABitmap est très bien codé, mais j'ai trouvé quelques incohérences dans le code et la façon de procéder
    Sinon tu peux également faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        LBmp:= SimpleStretch(LBmp, Round(1024*kZoom), Round(600*kZoom)) as TBGRABitmap;

    Bientôt ma solution pour gérer les bitmaps plus que 2/3 trucs à régler avant une "Beta version"

    A+

    Jérôme
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  9. #9
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 173
    Billets dans le blog
    9
    Par défaut
    Bonjour ! La façon recommandée d'utiliser la méthode Resample est la suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    BGRAReplace(image, image.Resample(image.Width * 10, image.Height * 10, rmSimpleStretch));
    La procédure BGRAReplace se charge de libérer la mémoire qui n'est plus utilisée. Cela est nécessaire car la méthode Resample crée une nouvelle image.

    Avec le code que vous avez montré au début (LBmp := LBmp.Resample(...) as TBGRABitmap;), vous perdez l'adresse de l'image initiale.

    Bonne continuation !

  10. #10
    Membre émérite
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 79
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 122
    Par défaut
    Citation Envoyé par BeanzMaster Voir le message
    ... Sinon tu peux également faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        LBmp:= SimpleStretch(LBmp, Round(1024*kZoom), Round(600*kZoom)) as TBGRABitmap;
    ...
    Ou bien je me trompe ou bien ce que tu me proposes est la même chose que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        LBmp:= TBGRABitmap(SimpleStretch(LBmp, Round(1024*kZoom), Round(600*kZoom)));
    Ce n'est qu'une forme différente d'écrire un transtypage ? En tous cas, le résultat est le même pour moi.

    Cordialement.

    Pierre

  11. #11
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 142
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 142
    Par défaut
    Bonjour,

    quand je parlais de "documenté", c'était dans le sens de l'infobulle que je présente ci-dessous, avec les deux lignes en bas en italique et couleur vert-bleu, qui s'affiche quand je mets la souris sur RawImage :
    Nom : infobulle.png
Affichages : 325
Taille : 29,5 Ko


    Quant à la complétion, j'attendais une réponse dans ce genre, où j'ai tapé aBitmap.RawImage.p et il s'est affiché ça :
    Nom : complétion.png
Affichages : 312
Taille : 6,6 Ko
    Si j'avais continué avec un "a", la dernière ligne aurait disparu et c'est dans cet esprit que je demandais pour "Re..."

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

Discussions similaires

  1. Problème de libération de mémoire avec free()
    Par Nival dans le forum Débuter
    Réponses: 8
    Dernier message: 18/03/2009, 23h06
  2. Problème de fuite de mémoire avec GTK+
    Par gwenhael dans le forum GTK+
    Réponses: 15
    Dernier message: 03/01/2008, 16h22
  3. Réponses: 11
    Dernier message: 16/07/2007, 16h33
  4. Pertes de mémoire avec Rave
    Par stepschn dans le forum Delphi
    Réponses: 8
    Dernier message: 15/10/2006, 11h18
  5. Problème de mémoire avec BDE
    Par Machuet dans le forum Bases de données
    Réponses: 3
    Dernier message: 13/07/2004, 10h11

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