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 :

Fichiers BMP d'un format 'spécial'


Sujet :

Langage Delphi

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 21
    Points : 11
    Points
    11
    Par défaut Fichiers BMP d'un format 'spécial' [Résolu]
    Bonjour

    J'envisage de me fabriquer un petit logiciel afin de ranger des BMP (plus de 3000) par 'similitude de contenu'. En fait, il s'agit de textures appliquées sur des modèles d'avions d'un simulateur de vol, que je souhaite classer selon divers critères et de manière itérative.

    Le problème, c'est que Delphi (V7) refuse une fois sur deux de charger ces fichiers dans un TBitmap, me communiquant régulièrement une erreur de lecture. Ce qui est d'autant plus bizarre, c'est que ces fichiers s'ouvrent très bien avec PaintShop (ou autres) !

    Ou peut donc se situer le problème, s'il vous plait ?

    Merci d'avance.
    Champy_33

  2. #2
    Membre confirmé
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Février 2006
    Messages
    537
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : Belgique

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2006
    Messages : 537
    Points : 460
    Points
    460
    Par défaut
    Bienvenu sur le forum,
    un petit bout de code ou une expliquation sur la façon dont tu charge tes BMP serait bien venu afin que l'on puisse t'aider.

    André
    Ils ne savaient pas que c'était impossible, alors ils l'ont fait !

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 21
    Points : 11
    Points
    11
    Par défaut
    OK, merci

    Voici l'exemple le plus simple qu'on puisse implémenter et qui, comme je l'ai expliqué plus haut, ne marche pas avec certains bmp.
    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
     
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
     
    type
      TForm1 = class(TForm)
        Button1: TButton;
        OD: TOpenDialog;
        procedure Button1Click(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
      Bit : TBitmap;
    begin
      if OD.Execute then begin
        Bit:=TBitmap.Create;
        Bit.LoadFromFile(OD.FileName);
        Bit.Free;
      end;
    end;
     
    end.

  4. #4
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Leader Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Points : 4 170
    Points
    4 170
    Par défaut
    Et quand ça ne marche pas, tu as qu'elle erreur exactement ?
    Est-ce que c'est toujours sur les mêmes images, ou est-ce que c'est au bout d'un certain nombre de lectures ?

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 21
    Points : 11
    Points
    11
    Par défaut
    L'erreur est tout simplement 'EReadError', autant dire que je n'en sais pas plus...
    J'ai tout de même remarqué qu'un fichier qui ne veut pas s'ouvrir une première fois, continue de réagir de même. Pour ceux qui se sont déjà ouverts, c'est très aléatoire...

  6. #6
    Membre éprouvé
    Avatar de CapJack
    Homme Profil pro
    Prof, développeur amateur vaguement éclairé...
    Inscrit en
    Mars 2004
    Messages
    624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Prof, développeur amateur vaguement éclairé...
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 624
    Points : 988
    Points
    988
    Par défaut
    J'ai très souvent eu ce problème, résolu parfois en chargeant le bitmap dans 'toshop, et en le sauvegardant sous un nom différent... TBitmap a vraiment des problèmes avec les bitmaps non standards.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 21
    Points : 11
    Points
    11
    Par défaut
    Merci CapJack

    J'ai moi aussi pensé à la solution qui consiste à ouvrir chaque fichier dans PaintShop et à le sauvegarder sous un autre nom. Cependant, je ne vois pas le faire pour plus de 3000 fichiers...
    J'aimerais simplement savoir pourquoi ça coince, afin d'y remédier de manière 'logicielle'.

    Champy

  8. #8
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Leader Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Points : 4 170
    Points
    4 170
    Par défaut
    L'erreur est tout simplement 'EReadError', autant dire que je n'en sais pas plus...
    Ca ne dit pas grand chose en effet...

    Dans ce cas, je ne vois qu'une seule façon d'avancer : Essaie de compiler l'appli avec les sources de la VCL (inclus le fichier Graphics.pas dans ton projet) et passe en debug dans le code de lecture du TBitmap.
    L'erreur doit probablement se déclencher quelque part dans TBitmap.ReadDIB.

    Ca devrait te permettre de comprendre ce qui se passe.

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 21
    Points : 11
    Points
    11
    Par défaut
    Bravo Franck.

    Ton pronostic s'avère parfait, car c'est en effet dans ReadDIB qu'il y a un problème. Cependant, j'ai beau suivre les lignes de code en 'pas à pas', j'avoue que je ne comprends pas trop ce qu'il se passe.
    L'erreur se déclenche au moment où l'appli a besoin de copier (lire) les bits de l'image dans un buffer - Stream.ReadBuffer(BitMem^,ImageSize)
    Visiblement, le nombre de données lues est différent de celui prévu et la procédure 'raise' une erreur.
    Il faut dire qu'il existe moult formats de fichiers et la taille de l'image est progressivement réduite au fur et à mesure que ses diverses entêtes sont lues. Mais ne connaissant pas le format 'exact' de mes fichiers, je ne peux malheureusement pas deviner où il y a une erreur...

    Merci dans tous les cas. Mais je crois que je n'irai pas plus loin, parce que ça dépasse un peu mes modestes compétences.
    Je trouve quand même étonnant qu'aucun fana de jeux n'ait rencontré (et résolu) ce problème avant moi.

    Champy

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 21
    Points : 11
    Points
    11
    Par défaut
    Bonjour

    A force de 'bricoler' pendant de longues heures d'énervement, j'ai enfin trouvé comment remédier à mon problème de chargement de certains fichiers bmp.
    Il faut copier le fichier 'graphic.pas' d'origine dans son répertoire de sources, afin qu'il soit utilisé à la place de l'originel (Merci Franck). Ensuite, il faut modifier le code d'une de ses procédures comme suit :

    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 TBitmap.ReadDIB(Stream: TStream; ImageSize: LongWord; bmf: PBitmapFileHeader);
    ...
    ...
              try
    {$IFDEF LINUX}
                // I need to pre-touch the memory in 4096 byte increments to ensure
                // the read will succeed. WINE marks this memory as not present to
                // catch when we make changes to it. If we read directly into it
                // Linux will (correctly) terminate the read with a failure since an
                // exception occured during the read. We need to make sure these
                // exceptions are triggered in user space instead of kernel.
                for I := 1 to (ImageSize + 4095) div 4096 do
                  PByteArray(BitsMem)^[(I - 1) * 4096] := 0;
    {$ENDIF}
                //  !!! Il faut retirer 2 octets à l'ImageSize pour que ça marche !!!
                Stream.ReadBuffer(BitsMem^, ImageSize-2);
     
              except
                DeleteObject(BMHandle);
                raise;
              end;
    ...

    Voilà. Après cette minuscule modification, les bmp 'normaux' se chargent toujours sans problème (tout du moins ceux que j'ai en magasin...), ainsi que ceux issus du jeu de simulation de vol IL2 FB.
    En conclusion, je pense pouvoir avancer sans trop me tromper que le format de ces bmp ne respecte pas à la lettre un des standards 'normaux'. Néanmoins, je ne peux pas affirmer que les formats 'normaux' de bmp seront tous lus sans erreur suite à la modification que je propose.

    Si ça peut arranger quelques développeurs...

    Champy

  11. #11
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Leader Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Points : 4 170
    Points
    4 170
    Par défaut
    Néanmoins, je ne peux pas affirmer que les formats 'normaux' de bmp seront tous lus sans erreur suite à la modification que je propose.
    Vu le code que tu modifies, sur les formats "normaux" tu ne devrais pas avoir d'erreur. Par contre tu risques de perdre la couleur d'un ou deux pixels au début ou à la fin...

  12. #12
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 862
    Points : 11 312
    Points
    11 312
    Billets dans le blog
    6
    Par défaut
    je trouve ça dans mon Graphics.pas (D5)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
          with bmiHeader do
          begin
    //****
            if biSizeImage < ImageSize then ImageSize := biSizeImage;
    regarde si jamais tu as une différence entre les 2 bmiHeader.biSizeImage et ImageSize, à tout hasard
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 21
    Points : 11
    Points
    11
    Par défaut
    Merci
    Je vais vérifier ça dans les jours qui viennent.

    Champy

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

Discussions similaires

  1. [VB6] Convertion d'un fichier bmp en jpg
    Par WOLO Laurent dans le forum VB 6 et antérieur
    Réponses: 22
    Dernier message: 12/01/2015, 13h22
  2. convertir un fichier bmp en jpeg (sous visual)
    Par mateo.14 dans le forum MFC
    Réponses: 2
    Dernier message: 24/03/2005, 13h22
  3. Un fichier .bmp comme paramètre d'une Procédure stockée
    Par FONKOU dans le forum Bases de données
    Réponses: 2
    Dernier message: 28/10/2004, 17h56
  4. [JFormattedTextField]Format spécial
    Par eraim dans le forum Composants
    Réponses: 13
    Dernier message: 22/04/2004, 10h20
  5. [TP]Charger un fichier bmp
    Par flavien tetart dans le forum Turbo Pascal
    Réponses: 5
    Dernier message: 30/06/2002, 19h04

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