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

Langage Delphi Discussion :

Écrire un TBitmap dans un fichier


Sujet :

Langage Delphi

  1. #1
    Membre émérite
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Points : 2 466
    Points
    2 466
    Par défaut Écrire un TBitmap dans un fichier
    Bonjour à tous,
    je suppose l'existance d'une astuce pour sauver un TBitmap dans un fichier manuelement ; par "manuellement", j'entand sans passer par la procedure TBitmap.SaveToFile. Si je ne veux pas l'employer, c'esst parceque je dois sauver un type record contenant un TBitmap.

    Voici comment je m'y suis pris, sans succes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        BitmapSize := SizeOf(pointer(Map^.bitmap)^);
        BlockWrite(F, BitmapSize, SizeOf(BitmapSize));
        BlockWrite(F, Map^.bitmap, BitmapSize);
    puis
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        BitmapSize := Map^.bitmap.Height*Map^.bitmap.Width;
        BlockWrite(F, BitmapSize, SizeOf(BitmapSize));
        BlockWrite(F, Map^.bitmap, BitmapSize);
    Map est un pointeur vers un type record contenant un TBitmap qui a ete initialisé et chargé a partir d'un bitmap valide (possibilité de l'afficher grace a un TImage).

    J'espere que vous pourrez m'aider, et je vous en remercie.

  2. #2
    Membre du Club
    Inscrit en
    Mai 2005
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 49
    Points : 59
    Points
    59
    Par défaut

    je pense que tu est entrain de confondre pointeur et objet
    les pointeurs : c'est des adresse qui pointent sur un bloc memoire, la fonction BlockWrite copie le contenu de cette zone memoire dans le fichier.
    Les Objet : c'est presque des pointeur (ou une autre forme) dans le sense où il pointe vers plusieurs zones memoire (c'est vraiment schématique ce que je dit), Methode, champs, classe et classe patente, tables ..... il est donc impossible de copier le contenu d'un objet en batch comme tu a essayer de le faire.

    ce que je te propose :
    1ére possibilité :
    que tu sauvegarde la reference vers le fichier bitmap (le non di fichier).
    facile mais pas trop comode j dois dire.
    2éme possibilité :
    utiliser SaveToStream. mais c'est compliqué a mettre en place.
    3éme possibilité :
    que tu utilises un record
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
       tBitmapRec=Record
          ChankSize:Cardinal;
          Height:Cardinal;
          Width:Cardinal;
          BytePerPixel:Byte;
          Pixels:Array of Byte;
       end;
    et que tu codes deux routines
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       BitmapToRecod(Bmp:TBitmap; var BitmapRec:tBitmapRec); {pour charger un bitmap dans ton record}
    et la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       RecordToBitmap(BitmapRec:tBitmapRec):TBitmap; {pour generer un Tbitmap a partir de ton record}

  3. #3
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Question bête : tu veux sauver quoi, exactement ?? Un bitmap, c'est un bitmap, un fichier .BMP si tu préfères (l'API Win32 est truffée de code pour charger/sauver des BMP)...
    L'objet qui encapsule cette image, de type TBitmap donc, c'est du "consommable", ça se recrée à la demande lorsque le besoin s'en fait sentir.
    Tes méthodes ne peuvent pas marcher, parceque tu sauves un objet "complet", avec des champs qui dépendent de la manière dont il a été créé => au mieux, c'est le kaboum au rechargement. En plus, tu oublie de déréférencer le pointeur (si ça te rappelle quelque chose... ;-))

    Si tu veux sauvegarder ton bitmap, il te faut les éléments suivants :
    - Taille du bitmap,
    - Palette,
    - Pixels (ou scanlines).
    Vu que ça risque d'être pénible à faire à la main, autant utiliser l'objet TBitmap lui-même.

    Tu va créer un TMemoryStream, puis utiliser TBitmap.SaveToStream pour "créer" le BMP en RAM. Ensuite, il faut et il suffit de sauvegarder, dans ton fichier final, la taille T du fichier BMP résultant (pour pouvoir le "séparer" à la relecture), puis le contenu du TMemoryStream (T octets à "vider").

    A la relecture, tu lis la taille T du BMP, puis tu recharges un TMemoryStream créé pour l'occasion avec les T prochains octets du fichier. Tu fais un TBitmap.Create, puis TBitmap.LoadFromStream pour récupérer ton TBitmap.

    Est-ce que ça répond à ta question ?

  4. #4
    Membre chevronné
    Avatar de Clorish
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 474
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 474
    Points : 2 158
    Points
    2 158
    Par défaut
    En general je sauvegarde les donnees du bitmap manuelement selon mon propre format (histoire d'eviter une recuperation trop facile).

    Autrement j'opterais pour la solution de Mac Lak : TStream et copie du Stream dans le fichier via les methdoes de lecture Ecriture.

    De plus je me demande si il n'existe pas la possibilité de coper un stream dans un stream ..... donc un TMemory/File Stream pour definir le fichier de sauvegarde, tu copie tes donnes puis au moment du bitmap, tu copie drectmeent le stream du bitmap optenu par TBitmap.SaveToStream

  5. #5
    Membre émérite
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Points : 2 466
    Points
    2 466
    Par défaut
    Citation Envoyé par Mac LAK
    Tu va créer un TMemoryStream, puis utiliser TBitmap.SaveToStream pour "créer" le BMP en RAM. Ensuite, il faut et il suffit de sauvegarder, dans ton fichier final, la taille T du fichier BMP résultant (pour pouvoir le "séparer" à la relecture), puis le contenu du TMemoryStream (T octets à "vider").

    A la relecture, tu lis la taille T du BMP, puis tu recharges un TMemoryStream créé pour l'occasion avec les T prochains octets du fichier. Tu fais un TBitmap.Create, puis TBitmap.LoadFromStream pour récupérer ton TBitmap.

    Est-ce que ça répond à ta question ?
    Oui, je tente et je reviens pour donner le résultat. Merci.

  6. #6
    Membre émérite
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Points : 2 466
    Points
    2 466
    Par défaut
    Non, je n'y arrive pas. Je parviens à créer le flux, lui affecter le bitmap (MemoryStream.Size retourne bien la taille de mob bitmap), mais impossible de le sauver dans le fichier.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        // Ecriture du bitmap de la map dans le fichier F:
        MemoryStream := TMemoryStream.Create; // création du TMemoryStream permettant l'enregistrement du bitmap dans le fichier
        Map^.bitmap.SaveToSTream(MemoryStream); // enregisrement du bitmap dans le TMemomryStream
        BitmapSize := MemoryStream.Size;
        BlockWrite(F, BitmapSize, SizeOf(BitmapSize)); // taille
        BlockWrite(F, MemoryStream, BitmapSize); // bitmap
    La derniere ligne retourne une erreur lors de l'execution : http://yankee.sierra77.free.fr/screens/ScreenShot.2005.05.23.19.04.59.jpg

  7. #7
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par prgasp77
    La derniere ligne retourne une erreur lors de l'execution : http://yankee.sierra77.free.fr/screens/ScreenShot.2005.05.23.19.04.59.jpg
    Normal.

    Essaie plutôt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    BlockWrite(F, MemoryStream.Memory^, BitmapSize); // bitmap
    Un coup de F1, ça aide...

  8. #8
    Membre émérite
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Points : 2 466
    Points
    2 466
    Par défaut
    J'en suis un grand fan, j'ai appris Pascal et Delphi qu'a coup de F1. Mais l'aide de BlockWrite est vraiment peu clair
    Delphi syntax:

    procedure BlockWrite(var f: File; var Buf; Count: Integer [; var AmtTransferred: Integer]);

    Description

    F is an untyped file variable, Buf is any variable, Count is an expression of type Integer, and AmtTransferred is an optional variable of type Integer.
    Quoi qu'il en soit, je vous remercie tous pour votre aide.

  9. #9
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par prgasp77
    J'en suis un grand fan, j'ai appris Pascal et Delphi qu'a coup de F1. Mais l'aide de BlockWrite est vraiment peu clair
    En fait, je pensais surtout à l'aide de TMemoryStream... ;-) Dans un post précédent, je t'avais "montré" (invonlontairement, certes) qu'il est facile d'oublier de déréférencer le pointeur avec BlockWrite : tu viens encore une fois de le constater. De toutes façons, c'est le PAC (Piège A C...) classique et habituel avec BlockWrite...

    Pour TMemoryStream, ce n'est pas l'objet lui-même qu'il faut sauver (il n'a aucune espèce d'utilité), mais le buffer lui-même, accessible donc via la propriété Memory. En déréférençant le pointeur, bien sûr...

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

Discussions similaires

  1. Comment mettre un tbitmap dans un fichier typé.
    Par poly128 dans le forum Delphi
    Réponses: 7
    Dernier message: 16/10/2006, 00h00
  2. Comment écrire une section dans un fichier ini?
    Par Jayceblaster dans le forum Delphi
    Réponses: 5
    Dernier message: 26/06/2006, 14h08
  3. Réponses: 7
    Dernier message: 17/03/2006, 13h26
  4. Réponses: 8
    Dernier message: 13/10/2005, 21h24
  5. [FileWriter] écrire à la suite dans un fichier.
    Par LoLoSS dans le forum Entrée/Sortie
    Réponses: 3
    Dernier message: 24/06/2004, 14h56

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