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 :

Comment travailler avec un bmp mal formé, si on ne le sait pas [Lazarus]


Sujet :

Lazarus Pascal

  1. #1
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 717
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 717
    Points : 15 094
    Points
    15 094
    Par défaut Comment travailler avec un bmp mal formé, si on ne le sait pas
    Bonjour,

    (cette nouvelle discussion part d'un court échange dans le fil du composant TGifViewer, mais pour ne pas le polluer je redémarre ici, avec un soupçon d'édition des échanges.)

    Je voulais voir comment réagit le TFastBitmap proposé par BeanzMaster avec un .bmp mal formé, et la conclusion que j'en tire est la suivante : à gauche avec un TBitmap, à droite avec le TFastbimap (qui "rend" comme un TLazInftImage), en bas au milieu le viewer de Linux.

    Nom : tbitmap_vs_tfastbitmap2.png
Affichages : 639
Taille : 130,4 Ko

    Réponse intégrale de BeanzMaster recopiée ici pour comprendre la suite :
    Citation Envoyé par BeanzMaster Voir le message
    Je ne sais pas comment tu charges les BMP, mais il faut que tu fasses attention à l'ordre des composantes de couleur. Dans les fichiers BMP les couleurs sont codée au format BGR TFastBitmap sous linux est au format RGBA. Il faut donc inverser le Rouge et Bleu (procedure SwapRB) ou le faire dans ta procédure de chargement. Note le bmp que tu nous montre "FondRVB.Bmp" n'est pas mal formé c'est Lazarus qui le lit mal. Et comme je te l'ai dis jette un oeil dans BZImageFileBMP.pas que je t'ai passé. Je l'ai justement blindé de commentaires parce que j'en ai ch.... Tu y trouveras plein d'informations qui t'aideront, j'en suis sure avec ce format qui semble pourtant facile à prendre en charge. Il reste encore quelques erreurs notamment avec la compression RLE dans certain cas ou je ne gère pas les erreurs d'encodage correctement et quelques couleurs que je n'ai pas inversé (surtout les bmp os22x 8bits)

    Si tu veux des BMP bizarres et hors normes à tester : https://github.com/jdelauney/BMP-ImageTestSuite
    J'ai écrit "mal formé" dans le titre, Jérome n'est pas d'accord mais je ne vois pas quoi mettre d'autre, on en parle dans la suite...
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  2. #2
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 717
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 717
    Points : 15 094
    Points
    15 094
    Par défaut
    Citation Envoyé par BeanzMaster Voir le message
    Je ne sais pas comment tu charges les BMP, mais il faut que tu fasses attention à l'ordre des composantes de couleur.
    Je fais comme un pimpin qui n'est pas au courant, y a qu'à voir cet exemple de la page du wiki), utilisé ainsi (en détournant le projet GifViewer pour un accès simple à uFastBitmap) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    procedure TForm1.Button1Click(Sender: TObject);
    var
     fbmp: TFastBitmap;
     bmp: TBitmap;
    begin
      bmp:= TBitmap.Create;
      bmp.LoadFromFile('/chemin/FondRVB32bad.bmp');// fic d'origine s'appelle FondRVB.bmp, le mien c'est le même juste renommé
      pnlView.Canvas.Draw(0,0,bmp);
      fbmp:= TFastBitmap.Create;
      fbmp.ImportFromBitmap(bmp);
      fbmp.Draw(pnlView.Canvas, 300,0);
    end;
    Citation Envoyé par BeanzMaster Voir le message
    Note le bmp que tu nous montre "FondRVB.Bmp" n'est pas mal formé c'est Lazarus qui le lit mal.
    Je l'appelle "mal formé" parce que je ne sais pas comment l'appeler, d'autant plus qu'étant codé sur 32 bits, le simple fait de l'exporter sans rien changer depuis The Gimp vers un autre fichier rend celui-ci conforme à ce qu'on doit voir. La différence (il y en a une) c'est l'offset des datas dans le fichier : 54 pour le mauvais, 122 pour le bon. Mais à partir de là les datas sont identiques (difficile d'en juger car il y a une bande blanche de 28 px de haut au début de l'image)

    Citation Envoyé par BeanzMaster Voir le message
    Et comme je te l'ai dis jette un oeil dans BZImageFileBMP.pas que je t'ai passé.
    Non. Tant qu'il ne fait pas partie de la distrib officielle, je ne sors pas des rails.

    Citation Envoyé par BeanzMaster Voir le message
    Si tu veux des BMP bizarres et hors normes à tester : https://github.com/jdelauney/BMP-ImageTestSuite
    J'ai déjà. On verra ça plus tard.

    Pour le moment, on note que sur un simple coup d'œil il est impossible de distinguer un original mal fichu mais correctement ouvert avec TLazIntfImage/TFastBitmap si on met à part l'inversion R<>B, versus un rendu avec le viewer de Linux, ou avec The Gimp, ou avec ImageJ.

    Comment font ces logiciels, que le couple FreePascal/Lazarus n'est pas capable de reproduire ?
    Sur quelles données du fichier se basent-ils ?

    Pour y voir clair, l'éditeur hexa, en haut sur le bad (les données commencent à 5E9A), en bas sur le good (à 5EDE) (Note : 122-54=6810 soit 4416, et 5E9A+44=5EDE).
    J'ai coloré (en vieux rose, bleu pâle et beige) les 3 premiers pixels, on voit bien qu'il n'y a aucune différence, alors sur quoi se base FreePascal ?
    Nom : compar_fondRVB.png
Affichages : 506
Taille : 64,4 Ko

    Pour essayer de le savoir, j'ai doublé mon test :
    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
    procedure TMainForm.Button1Click(Sender: TObject);
    var
     fbmp: TFastBitmap;
     bmp: TBitmap;
    begin
      bmp:= TBitmap.Create;
      bmp.LoadFromFile('/datas/_share_4_VM/Programmation/FondRVB32bad.bmp');// fic d'origine s'appelle FondRVB.bmp, le mien c'est le même juste renommé
      pnlView.Canvas.Draw(0,0,bmp);
      fbmp:= TFastBitmap.Create;
      fbmp.ImportFromBitmap(bmp);
      fbmp.Draw(pnlView.Canvas, 300,0);
      fbmp.Free;
      bmp.Free;
     
      bmp:= TBitmap.Create;
      bmp.LoadFromFile('/datas/_share_4_VM/Programmation/FondRVB32_ok.bmp');// généré par The Gimp depuis le fic d'origine
      pnlView.Canvas.Draw(0,300,bmp);
      fbmp:= TFastBitmap.Create;
      fbmp.ImportFromBitmap(bmp);
      fbmp.Draw(pnlView.Canvas, 300,300);
      fbmp.Free;
      bmp.Free;
    end;
    mais ça coince sur la ligne fbmp.ImportFromBitmap(bmp); :
    Nom : erreur_sur_ok.png
Affichages : 559
Taille : 126,5 Ko

    et là, ça me dépasse.
    Tiens, je recopie l'endroit concerné :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    procedure TColor32.SetColorComponent(Index: Integer; aValue: Byte);
    Begin
      v[Index] := aValue; // ligne 317 c'est elle
    End;
    Au moment du plantage l'index vaut 3 et aValue 255.

    On notera que le TBitmap a correctement affiché l'image, cette fois.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  3. #3
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 717
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 717
    Points : 15 094
    Points
    15 094
    Par défaut Effet de bord épouvantablement pervers !
    J'ai dit que TFastBitmap affichait le mauvais .bmp comme un TLazIntfImage. J'ai voulu vérifier ce point et là, patatras, le TLazIntfImage se met à afficher des traits verticaux !

    Je vous la fais courte car je fatigue, à force, et si Gilles passe par là, il verra bien qu'on a affaire à du vaudou mal intentionné, regardez bien ces lignes de code, quasiment identiques sauf celle qui dessine le bmp sur le canvas du TPanel, présente en haut et absente en bas, et c'est sa présence qui met la pagaille !
    Je vous laisse imaginer la quantité de tests pour trouver ça, car c'est juste impensable, donc inenvisageable, et pourtant...

    Nom : panel_problem.gif
Affichages : 959
Taille : 94,1 Ko

    Désolé pour le rendu des couleurs, mais la compression gif ça vaut vraiment rien, :aie;

    En quoi le dessin d'un bmp sur le canvas d'un panel impacterait ce bmp ? Ne marcherait-on pas sur la tête, là ?

    Ceux qui veulent jouer trouveront leur bonheur là-dessous (sauf la ligne qui casse tout) :

    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
    procedure TForm1.Button6Click(Sender: TObject);
    var  
    // http://wiki.freepascal.org/Developing_with_Graphics#Conversion_between_TLazIntfImage_and_TBitmap
    // http://wiki.freepascal.org/Developing_with_Graphics#Loading_a_TLazIntfImage_into_a_TImage
      b: TBitmap;
      t: TLazIntfImage;
    begin
      If Not opd.Execute Then Exit; // ajout perso
     
      b := TBitmap.Create;
      try
        b.LoadFromFile(opd.FileName);
        t := b.CreateIntfImage;
     
        // Read and/or write to the pixels
    //    t.Colors[10,20] := colGreen; // tuto1, inutile ici
     
    //    b.LoadFromIntfImage(t); // tuto1, inutile ici
        Image1.Width := t.Width; Image1.Height:= t.Height; // ajout perso
        Image1.Picture.Bitmap.LoadFromIntfImage(t); // tuto2
      finally
        t.Free;
        b.Free;
      end;
    end;
    Nota : quand l'image est bad, elle a parfois une ligne noire en bas à droite, de longueur variable, et avec plus ou moins de pixels pas noirs (là en l'espèce, un seul bleu à gauche, visible dans l'agrandissement) :
    Nom : aff_bon_mais_faux.png
Affichages : 488
Taille : 37,6 Ko

    Comparez avec le gif, où cette barre est beaucoup plus courte.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  4. #4
    Expert confirmé
    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
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Salut, je vais répondre message par message

    Citation Envoyé par Jipété Voir le message
    Je fais comme un pimpin qui n'est pas au courant, y a qu'à voir cet exemple de la page du wiki), utilisé ainsi (en détournant le projet GifViewer pour un accès simple à uFastBitmap) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    procedure TForm1.Button1Click(Sender: TObject);
    var
     fbmp: TFastBitmap;
     bmp: TBitmap;
    begin
      bmp:= TBitmap.Create;
      bmp.LoadFromFile('/chemin/FondRVB32bad.bmp');// fic d'origine s'appelle FondRVB.bmp, le mien c'est le même juste renommé
      pnlView.Canvas.Draw(0,0,bmp);
      fbmp:= TFastBitmap.Create;
      fbmp.ImportFromBitmap(bmp);
      fbmp.Draw(pnlView.Canvas, 300,0);
    end;

    Je l'appelle "mal formé" parce que je ne sais pas comment l'appeler, d'autant plus qu'étant codé sur 32 bits, le simple fait de l'exporter sans rien changer depuis The Gimp vers un autre fichier rend celui-ci conforme à ce qu'on doit voir. La différence (il y en a une) c'est l'offset des dats dans le fichier : 54 pour le mauvais, 122 pour le bon. Mais à partir de là les datas sont identiques (difficile d'en juger car il y a une bande blanche de 28 px de haut au début de l'image)
    Pourquoi 54 et 122 ? 54 Correspond à un BMP version 1 et 122 à un BMP Version 4

    D'abord on à un en-tête commun

    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
    Type
      { L'entête principale d'un fichier BMP est composée de 4 champs :@br
        - La signature (sur 2 octets), indiquant qu'il s'agit d'un fichier BMP à l'aide de 2 caractères :
        @unorderedList(
          @item( BM $424D en hexadécimal, indique qu'il s'agit d'un Bitmap Windows.)
          @item( BA $4241 indique qu'il s'agit d'un Bitmap OS/2.)
          @item( CI $4349 indique qu'il s'agit d'une icone couleur OS/2.)
          @item( CP $4350 indique qu'il s'agit d'un pointeur de couleur OS/2.)
          @item( IC $4943 indique qu'il s'agit d'une icone OS/2.)
          @item( PT $5054 indique qu'il s'agit d'un pointeur OS/2.)
        - La taille totale du fichier en octets (codée sur 4 octets)@br
        - 2 champs réservés (de 2 octets)@br
        - L'offset de l'image (sur 4 octets), en français décalage }
      TBZBMPFileHeader = Packed Record   // < Taille de l'en-tête commune 14 octets
        bfType: Array[0..1] Of Char;  // bfType, Normalement Word;@brEn déclarant un array of char on evite de se prendre la tête avec  le "Little et Big Endian"
        bfSize: Longword;                // Taille totale du fichier
        bfReserved1: Word;             // Hospot X -> OS2x
        bfReserved2: Word;             // Hospot Y -> OS2x
        bfOffBits: Longword;           // Position des données de l'image dans le fichier
      End;
    L'en-tête pour la version 1

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
      { En-têtes BMP OS/2 V2@br
        biSize: LongWord; Taille de l'en-tête  =  40 octets  }
      TBZWindowsBMPInfoHeaderV1 = Packed Record   // Ici Taille 36, biSize est lu avant
        biWidth: Longint;                     // Largeur de l'image en pixels
        biHeight: Longint;                   // Hauteur de l'image en pixels
        biPlanes: Word;                      // Nombre de Plans de couleur  = 1
        biBitCount: Word;                   // Nombre de bits par pixel
        biCompression: Longword;      // Type de compression
        biSizeImage: Longword;         // Taille de l'image  AVEC LE PADDING
        biXPixelsPerMeter: Longint;     // Nombre de pixel horizontal par mètre
        biYPixelsPerMeter: Longint;     // Nombre de pixel vertical par mètre
        biClrUsed: Longword;             // Nombre de couleurs utilisées (0 = toutes)
        biClrImportant: Longword;      // Nombre de couleurs importantes (0 = toutes)
      End;
    40 + 14 = 54 octets

    L'en-tête pour la version 4

    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
      { Definitions pour la prise en charge type de couleur spéciale CIExyz@br
       dans les en-têtes Windows V4 et V5
       @groupbegin }
      TBZBMP_CIEXYZCoord = Packed Record
        X: Longint;
        Y: Longint;
        Z: Longint;
      End;
     
      TBZBMP_CIEXYZCoordTriple = Packed Record
        CRed: TBZBMP_CIExyzCoord;
        CGreen: TBZBMP_CIExyzCoord;
        CBlue: TBZBMP_CIExyzCoord;
      End;
     
      { En-tête BMP Windows V4@br
        biSize: LongWord; Taille de l'en-tête  = 108 octets }
      TBZWindowsBMPInfoHeaderV4 = Packed Record   //< Ici Taille 104, biSize est lu avant
        biWidth: Longint;                         // Largeur de l'image en pixels
        biHeight: Longint;                       // Hauteur de l'image en pixels
        biPlanes: Word;                          // Nombre de Plans de couleur  = 1
        biBitCount: Word;                       // Nombre de bits par pixel
        biCompression: Longword;          // Type de compression
        biSizeImage: Longword;             // Taille de l'image  AVEC LE PADDING peut être 0 si pas de compression
        biXPixelsPerMeter: Longint;        // hoizontal pixels per meter
        biYPixelsPerMeter: Longint;        // vertical pixels per meter
        biClrUsed: Longword;                // Nombre de couleurs utilisées (0 = toutes)
        biClrImportant: Longword;        // Nombre de couleurs importantes (0 = toutes)
        biRedMask: Longword;              // Masque Couleur Rouge
        biGreenMask: Longword;          //< Masque Couleur Vert
        biBlueMask: Longword;            //< Masque Couleur Bleu
        biAlphaMask: Longword;          //< Masque Couleur Alpha
        biCSType: Longword;              //< Type de l'espace de couleur CIE
        biEndpoints: TBZBMP_CIEXYZCoordTriple; //< "Color space endpoints"
        biGammaRed: Longword;            // Correction Gamma Rouge
        biGammaGreen: Longword;        // Correction Gamma Vert
        biGammaBlue: Longword;          // Correction Gamma Bleu
      End;
    On à donc bien 14 + 108 = 122 octets

    La différence est là, si les datas sont identiques, c'est ce que je te disais le bmp n'est pas mal formé, mais mal lu. C'est histoire de hachure viens du fait que Lazarus le prend pour un 24 bit alors que c'est un 32 bit
    On avait d'ailleurs déja bien galérer ici

    Citation Envoyé par Jipété Voir le message
    Pour le moment, on note que sur un simple coup d'œil il est impossible de distinguer un original mal fichu mais correctement ouvert avec TLazIntfImage/TFastBitmap si on met à part l'inversion R<>B, versus un rendu avec le viewer de Linux, ou avec The Gimp, ou avec ImageJ.

    Comment font ces logiciels, que le couple FreePascal/Lazarus n'est pas capable de reproduire ?
    Sur quelles données du fichier se basent-ils ?

    Pour y voir clair, l'éditeur hexa, en haut sur le bad (les données commencent à 5E9A), en bas sur le good (à 5EDE) (Note : 122-54=6810 soit 4416, et 5E9A+44=5EDE).
    J'ai coloré (en vieux rose, bleu pâle et beige) les 3 premiers pixels, on voit bien qu'il n'y a aucune différence, alors sur quoi se base FreePascal ?
    Lazarus se prend les pied à cause de son calcul avec la composante Alpha et certain BMP codés en 32bits

    Citation Envoyé par Jipété Voir le message
    Pour essayer de le savoir, j'ai doublé mon test :
    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
    procedure TMainForm.Button1Click(Sender: TObject);
    var
     fbmp: TFastBitmap;
     bmp: TBitmap;
    begin
      bmp:= TBitmap.Create;
      bmp.LoadFromFile('/datas/_share_4_VM/Programmation/FondRVB32bad.bmp');// fic d'origine s'appelle FondRVB.bmp, le mien c'est le même juste renommé
      pnlView.Canvas.Draw(0,0,bmp);
      fbmp:= TFastBitmap.Create;
      fbmp.ImportFromBitmap(bmp);
      fbmp.Draw(pnlView.Canvas, 300,0);
      fbmp.Free;
      bmp.Free;
     
      bmp:= TBitmap.Create;
      bmp.LoadFromFile('/datas/_share_4_VM/Programmation/FondRVB32_ok.bmp');// généré par The Gimp depuis le fic d'origine
      pnlView.Canvas.Draw(0,300,bmp);
      fbmp:= TFastBitmap.Create;
      fbmp.ImportFromBitmap(bmp);
      fbmp.Draw(pnlView.Canvas, 300,300);
      fbmp.Free;
      bmp.Free;
    end;
    et là, ça me dépasse.
    Tiens, je recopie l'endroit concerné :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    procedure TColor32.SetColorComponent(Index: Integer; aValue: Byte);
    Begin
      v[Index] := aValue; // ligne 317 c'est elle
    End;
    Au moment du plantage l'index vaut 3 et aValue 255.

    On notera que le TBitmap a correctement affiché l'image, cette fois.
    C'est sur le 1er ou le 2eme appel que tu te prend le SIGSEGV ?

    Sin en partant de ton BMP fournit ici Je suppose que c'est bien le même

    Sous windows l'affichage est correcte avec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    procedure TMainForm.Button1Click(Sender: TObject);
    var
     fbmp: TFastBitmap;
     bmp: TBitmap;
    begin
      bmp:= TBitmap.Create;
      bmp.LoadFromFile('/datas/_share_4_VM/Programmation/FondRVB32bad.bmp');// fic d'origine s'appelle FondRVB.bmp, le mien c'est le même juste renommé
      pnlView.Canvas.Draw(0,0,bmp);
      fbmp:= TFastBitmap.Create;
      fbmp.ImportFromBitmap(bmp);
      fbmp.Draw(pnlView.Canvas, 300,0);
      fbmp.Free;
      bmp.Free;
    end;
    Nom : 2018-07-12_154514.jpg
Affichages : 525
Taille : 27,4 Ko

    Comme on peux le voir ici par d'inversion R et B. Il faudra donc que je revois ma copie pour "ImportFromBitmap" ici c'est correct car le format de FastBitmap est BGRA donc identique à celui du bitmap.

    Je vais allez tester sous Linux et je ferais un petit edit

    EDIT : De retour sous linux

    Premier test sans rien changer :

    Nom : Screenshot_20180712_161714.jpeg
Affichages : 565
Taille : 35,2 Ko

    Maintenant petite rectification à faire dans uFastBitmap

    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
    Function TFastBitmap.ImportFromRawImage(Const ARawImage: TRawImage): Boolean;
    var
      BufferData : PByte;
    begin
      SetSize(ARawImage.Description.Width,ARawImage.Description.Height);
      result:=false;
      // On verifie si la taille des deux tampons sont identique
      // Si ce n'est pas le cas, cela veut dire que le TRawImage n'est pas au format 32bit
      if (ARawImage.DataSize= FSize) then
      begin
        try
          BufferData := PByte(Self.getSurfaceBuffer);
          Move(ARawImage.Data^, BufferData^, self.Size);
          {$IFDEF WINDOWS}
               if (ARawImage.Description.RedShift = 0) and ((ARawImage.Description.BlueShift = 16)) then Self.SwapRB; // Le RawImage est-il en RGB, si oui on échange
          {$ELSE}       
              if (ARawImage.Description.RedShift = 16) and ((ARawImage.Description.BlueShift = 0)) then Self.SwapRB; // Le RawImage est-il en BGR, si oui on échange
          {$ENDIF}
        finally
          result:=true;
        end;
      end;
    End;
    Résultat

    Nom : Screenshot_20180712_162638.jpeg
Affichages : 543
Taille : 35,2 Ko

    RE-EDIT : Afin d'être synchrone j'ai fais un zip du petit test à decompresser dans un sous dossier du dossier Demos de TGIFViewer : BMPTest.zip
    • "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

  5. #5
    Expert confirmé
    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
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Jipété Voir le message
    En quoi le dessin d'un bmp sur le canvas d'un panel impacterait ce bmp ? Ne marcherait-on pas sur la tête, là ?
    Cela vien du TRawImage qui est mal remplis Non en fait le RawImage est remplis correctement. Il semblerai que cela vienne du StretchDraw utilisé par le Widget GTK qui est en cause. J'essayerai de trouvé ou se cache cette procedure pour y jeter un oeil.

    Citation Envoyé par Jipété Voir le message
    Ceux qui veulent jouer trouveront leur bonheur là-dessous (sauf la ligne qui casse tout) :

    Nota : quand l'image est bad, elle a parfois une ligne noire en bas à droite, de longueur variable, et avec plus ou moins de pixels pas noirs (là en l'espèce, un seul bleu à gauche, visible dans l'agrandissement) :
    A l'heure actuelle TLazIntfImage est la meilleur solution pour la gestion des bitmap surtout sous Linux, on à vu le problème liée à la transparence dans TGifViewer.

    Citation Envoyé par Jipété Voir le message
    Comparez avec le gif, où cette barre est beaucoup plus courte.
    Ca c'est un erreur qui vient de la FCL, surement une petite embrouille avec un TRect dans le code du TLazIntfImage. J'ai fais quelques tests il y à 1 ou 2 semaine en utilisant juste la FCL cf chez les voisins
    • "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
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 717
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 717
    Points : 15 094
    Points
    15 094
    Par défaut
    Yop !

    Citation Envoyé par BeanzMaster Voir le message
    C'est sur le 1er ou le 2eme appel que tu te prends le SIGSEGV ?
    Sur le 2e. Je ne l'ai pas indiqué ? Désolé, ça me semblait évident, puisque le 2e appel est rajouté sous le 1er et ses deux images moisies, l'une avec ses traits et l'autre avec ses couleurs inversées.
    Allez, au boulot,
    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
    procedure TMainForm.Button1Click(Sender: TObject);
    var
     fbmp: TFastBitmap;
     bmp: TBitmap;
    begin
      bmp:= TBitmap.Create;
      bmp.LoadFromFile('/datas/_share_4_VM/Programmation/FondRVB32bad.bmp'); // fic d'origine s'appelle FondRVB.bmp, le mien c'est le même juste renommé
      pnlView.Canvas.Draw(0,0,bmp);  // traits à gauche
     
      fbmp:= TFastBitmap.Create;
      fbmp.ImportFromBitmap(bmp);
      fbmp.Draw(pnlView.Canvas, 300,0);  // couleurs inversées à droite
      fbmp.Free;
      bmp.Free;
     
      bmp:= TBitmap.Create;
      bmp.LoadFromFile('/datas/_share_4_VM/Programmation/FondRVB32_ok.bmp');// généré par The Gimp depuis le fic d'origine
      pnlView.Canvas.Draw(0,300,bmp);
      fbmp:= TFastBitmap.Create;
      fbmp.ImportFromBitmap(bmp); // SIGSEGV là ! <<<<<<<<<<<<<<<<<<
      fbmp.Draw(pnlView.Canvas, 300,300);
      fbmp.Free;
      bmp.Free;
    end;

    Citation Envoyé par BeanzMaster Voir le message
    Sinon en partant de ton BMP fourni ici je suppose que c'est bien le même
    Quelle mémoire ! Je ne me souvenais pas d'avoir déjà parlé de ça : je tourne en rond et je marche dans mes traces, comme les Dupond dans je ne sais plus quel Tintin On a marché sur la Lune...
    Et oui, c'est tout-à-fait ça.

    Citation Envoyé par BeanzMaster Voir le message
    Sous windows l'affichage est correcte avec
    Sous Windows l'affichage est toujours correct, !

    Citation Envoyé par BeanzMaster Voir le message
    Maintenant petite rectification à faire dans uFastBitmap
    En effet c'est bon, maintenant. Et j'ai récupéré ton prog de test, mais une dernière question : comment faire en sorte que l'affichage ne disparaisse pas quand on recouvre puis découvre la fenêtre ? Le panel ne "maintient" pas l'image...
    EDIT :
    Citation Envoyé par BeanzMaster Voir le message
    Maintenant petite rectification à faire dans uFastBitmap
    si je peux me permettre :
    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
    Function TFastBitmap.ImportFromRawImage(Const ARawImage: TRawImage): Boolean;
    var
      BufferData : PByte;
    begin
      SetSize(ARawImage.Description.Width,ARawImage.Description.Height);
      result:=false;
      // On verifie si les tailles des deux tampons sont identiques
      // Si ce n'est pas le cas, cela veut dire que le TRawImage n'est pas au format 32bit et donc qu'est-ce qu'on fait ?
      if (ARawImage.DataSize= FSize) then
      begin
        try
          BufferData := PByte(Self.getSurfaceBuffer);
          Move(ARawImage.Data^, BufferData^, self.Size);
          {$IFDEF WINDOWS}
             if (ARawImage.Description.RedShift = 0)  and ((ARawImage.Description.BlueShift = 16)) then Self.SwapRB; // Le RawImage est-il en RGB, si oui on échange
          {$ELSE}       
             if (ARawImage.Description.RedShift = 16) and ((ARawImage.Description.BlueShift = 0))  then Self.SwapRB; // Le RawImage est-il en BGR, si oui on échange
          {$ENDIF}
        finally
          result:=true;
        end;
      // end;
      end else // tailles différentes
      begin
      // qu'est-ce qu'on fait ?
      end;
    End;
    /EDIT

    Citation Envoyé par BeanzMaster Voir le message
    A l'heure actuelle TLazIntfImage est la meilleure solution pour la gestion des bitmap surtout sous Linux, on a vu le problème lié à la transparence dans TGifViewer.
    Non, puisqu'il se plante sur l'inversion des couleurs R<>B comme je l'ai montré dans le 1er post (le triangle en haut à gauche doit être dans les orange-marron et pas bleu !)
    Oui, je sais, cette image abstraite est très trompeuse, affichée seule s'il n'y a pas le bout de noir en bas à droite, on se trompe facilement !

    Citation Envoyé par BeanzMaster Voir le message
    Ca c'est un erreur qui vient de la FCL, surement une petite embrouille avec un TRect dans le code du TLazIntfImage. J'ai fait quelques tests il y a 1 ou 2 semaine en utilisant juste la FCL cf chez les voisins
    Ouaip, j'ai tout lu, j'ai même récupéré un petit prog en fin de 1re page, mais il a le même problème qu'ici.
    Par contre, quelqu'un t'a suggéré la librairie Vampyre et je dois dire que celle-ci ouvre correctement le fichier bad ! Pas de traits verticaux, pas d'inversion de couleurs avec la démo Image_Browser (qui remonte un format A8R8G8B8 pour ce fichier maudit).

    Nom : fondrvb_sur_vampyre.png
Affichages : 463
Taille : 42,6 Ko
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  7. #7
    Expert confirmé
    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
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Jipété Voir le message
    Yop !


    Sur le 2e. Je ne l'ai pas indiqué ? Désolé, ça me semblait évident, puisque le 2e appel est rajouté sous le 1er et ses deux images moisies, l'une avec ses traits et l'autre avec ses couleurs inversées.

    Non, puisqu'il se plante sur l'inversion des couleurs R<>B comme je l'ai montré dans le 1er post (le triangle en haut à gauche doit être dans les orange-marron et pas bleu !)
    Oui, je sais, cette image abstraite est très trompeuse, affichée seule s'il n'y a pas le bout de noir en bas à droite, on se trompe facilement !

    Allez, au boulot,
    Ok je vais tester. Juste une petite question le fichier générer avec Gimp quelles options as tu appliqué ? 32 bits --> X8 R8 G8 B8 ?

    Citation Envoyé par Jipété Voir le message
    En effet c'est bon, maintenant. Et j'ai récupéré ton prog de test, mais une dernière question : comment faire en sorte que l'affichage ne disparaisse pas quand on recouvre puis découvre la fenêtre ? Le panel ne "maintient" pas l'image...
    Il faut passer par l'évènement OnPaint du panel. Et dans le formCreate ajouter Doublebuffered := true;
    Citation Envoyé par Jipété Voir le message
    EDIT :

    si je peux me permettre :
    Il faudrait en effet rajouté un commentaire comme quoi cette fonction marche qu'avec des bitmap 32 bits. Ou faudrait que je la passe dans protected afin qu'elle ne soit pas disponible pour l'utilisateur final. Si tu regardes ImportFromBmp tu remarqueras que tous les bitmaps différents de 32 bits est convertit dans ce format avant d'appeler ImportFromRawImage. Et ce tout simplement car notre TFastBitmap est en 32 bits.


    Citation Envoyé par Jipété Voir le message
    Ouaip, j'ai tout lu, j'ai même récupéré un petit prog en fin de 1re page, mais il a le même problème qu'ici.
    Par contre, quelqu'un t'a suggéré la librairie Vampyre et je dois dire que celle-ci ouvre correctement le fichier bad ! Pas de traits verticaux, pas d'inversion de couleurs avec la démo Image_Browser (qui remonte un format A8R8G8B8 pour ce fichier maudit).
    Effectivement JP me l'a suggéré , mais vu que je bosse sur ma solution. Bref un si jamais tu as toujours DragZNView sous la main tu peux également tester avec (même si je sais que certain BMP ne s'afficheront pas correctement avec la version que je t'ai passé)

    Là il me remonte un format BGRA et on peux le vérifier avec les infos "bitfields" maintenant Vampyre renvoie l'inverse ARGB <> BGRA. Et pour ce coup je suis sûre des infos remontés par mes outils car sinon l'affichage serait en vrac

    Nom : 2018-07-12_225232.jpg
Affichages : 559
Taille : 135,6 Ko
    • "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

  8. #8
    Expert confirmé
    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
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Pour le SIGSegv c'est une erreur d'inattention de ma part.

    Dans Function TFastBitmap.ImportFromBitmap(Const ABitmap: Graphics.TBitmap): Boolean;il faut modifier la sous procedure setAlpha comme ceci

    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
      procedure SetAlpha(Value : Byte);
      var
        i : Integer;
        PixPtr : PColor32;
        maxi : Integer;
      begin
        i:=0;
        Maxi := (FWidth * FHeight)-1;
        PixPtr :=PColor32(FData);// Self.GetScanLine(0);
        While i<Maxi do
        begin
          PixPtr^.Alpha:= Value;
          inc(PixPtr);
          inc(i);
        end;
      end;
    Et oui j'avais prix FSize comme référence qui la taille du tampon en octet et non le nombre total de pixel. On pourrais d'ailleurs rajouté une variable dans FTotalPixel ou un truc dans le genre dans Private ou protected et qui serait calculée dans la procedure SetSizeSinon ce qui est drôle c'est que cette procédure est appelée seulement si le TBitmap n'est pas un 32 Bits

    Voilà d'ailleurs les infos du RawImage.Description du TBitmap

    Nom : 2018-07-12_233050.jpg
Affichages : 489
Taille : 50,9 Ko

    Il est clair que Lazarus se prend les pieds dans le tapis avec ce genre de bmp et fait sa mayonnaise interne

    et voila les infos retournées par DragZNView

    Nom : 2018-07-12_233648.jpg
Affichages : 873
Taille : 73,8 Ko
    • "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
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 717
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 717
    Points : 15 094
    Points
    15 094
    Par défaut
    Citation Envoyé par BeanzMaster Voir le message
    Ok je vais tester. Juste une petite question le fichier générer avec Gimp quelles options as tu appliqué ? 32 bits --> X8 R8 G8 B8 ?
    avec The Gimp en mode 32 bits, j'utilise ARGB en général.

    Citation Envoyé par BeanzMaster Voir le message
    Effectivement JP me l'a suggéré , mais vu que je bosse sur ma solution. Bref un si jamais tu as toujours DragZNView sous la main tu peux également tester avec (même si je sais que certain BMP ne s'afficheront pas correctement avec la version que je t'ai passée)
    non, je ne l'ai pas gardé, je me noie sous les codes arrivant de tous les côtés...

    Citation Envoyé par BeanzMaster Voir le message
    Là il me remonte un format BGRA et on peux le vérifier avec les infos "bitfields" maintenant Vampyre renvoie l'inverse ARGB <> BGRA. Et pour ce coup je suis sûre des infos remontés par mes outils car sinon l'affichage serait en vrac.
    J'ai peut-être une explication : voilà ce qu'on trouve dans la procedure TMainForm.LoadFile; de Main.pas du projet VCLimageBrowser :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
          for I := 0 to FImage.ImageCount - 1 do
          begin
            FImage.ActiveImage := I;
            FOriginalFormats[I] := FImage.Format;
            // Convert image to 32bit ARGB format if current format is not supported by canvas class
            if not (FImage.Format in TImagingCanvas.GetSupportedFormats) then
              FImage.Format := ifA8R8G8B8;
          end;
    Donc un fichier RGB s'affiche dans le label comme RGB, un vrai fichier ARGB indique ARGB, tout comme un fichier mal supporté tel qu'indiqué ci-dessus, et un fichier XRGB issu de Gimp affichera ARGB et une couleur fausse...

    Ceci étant dit, j'ai l'impression qu'on n'est pas sorti de l'auberge, dans la mesure où on ne sait pas où on va, exemple avec ce micro-programme qui va générer un fichier 24 bits ou un 32 bits XRGB, X sans que je sache pourquoi ; tout ce qu'il faut c'est un bouton et un radiogroup avec 2 items : 24 bits et 32 bits.
    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
    procedure TForm1.Button1Click(Sender: TObject);
    var
      bmp : Tbitmap;
      function DateOfYear: string;
      var 
        aYear,M,D: Word;
      begin
        DecodeDate(Now,AYear,M,D);
        Result := IntToStr(Trunc(Now-EncodeDate(AYear,1,1))+1);
      end;
    begin
      bmp := Tbitmap.create;
      try
        case rdgPixelFormat.ItemIndex of
          0: bmp.pixelformat := pf24bit;
          1: bmp.pixelformat := pf32bit;
        end;
        bmp.width  := 60;
        bmp.height := 48;
        with bmp.Canvas do
        begin
          Brush.Color := clRed;
          //remplir avec le pinceau le rectangle à la dimension du canvas
          FillRect(ClipRect);
        end;
        case rdgPixelFormat.ItemIndex of
          0: bmp.SaveToFile(FileUtil.ProgramDirectory+DateOfYear+'_'+FloatToStr(Int(Frac(Now)*100000))+'_24.bmp');
          1: bmp.SaveToFile(FileUtil.ProgramDirectory+DateOfYear+'_'+FloatToStr(Int(Frac(Now)*100000))+'_32.bmp');
        end;
      finally
        bmp.free;
      end;
    end;
    Et comment je sais que c'est X ? Le projet Vampyre :
    Nom : xrgb.png
Affichages : 462
Taille : 5,8 Ko

    Mais Vampyre c'est un truc de fou : le label change de caption en fonction du type de fichier rencontré, mais je ne trouve pas où l'affectation est faite (ou alors ils ont mélangé des bouts de l'ihm avec les codes métier ?)

    Va aussi falloir maintenant que je compare en hexa les fichiers XRGB créés par The Gimp et mal affichés par Vampyre et ceux créés par bmp.SaveToFile bien affichés par Vampyre : c'est l'enfer ce truc,


    Citation Envoyé par BeanzMaster Voir le message
    et voila les infos retournées par DragZNView

    Nom : 2018-07-12_233648.jpg
Affichages : 873
Taille : 73,8 Ko
    Je ne comprends pas cette image : si la taille en bits du canal Alpha est 0 (encadré mauve en bas), Bits par pixel ne peut pas être 32 ! 8+8+8+0=24, bon sang !

    Quant à l'autre image, issue de RawImage.Description, il me semblait qu'on avait vu, il y a longtemps, que ces résultats n'étaient pas fiables, non ?
    Et j'aimerais bien savoir comment sont trouvées/récupérées les valeurs correspondant aux différents Shifts et Precs...


    Citation Envoyé par BeanzMaster Voir le message
    Il faut passer par l'évènement OnPaint du panel.
    Qui n'existe pas...

    Citation Envoyé par BeanzMaster Voir le message
    Et dans le formCreate ajouter Doublebuffered := true;
    Parait que ça sert à rien sous Linux.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  10. #10
    Expert confirmé
    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
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Jipété Voir le message

    Je ne comprends pas cette image : si la taille en bits du canal Alpha est 0 (encadré mauve en bas), Bits par pixel ne peut pas être 32 ! 8+8+8+0=24, bon sang !

    Quant à l'autre image, issue de RawImage.Description, il me semblait qu'on avait vu, il y a longtemps, que ces résultats n'étaient pas fiables, non ?
    Et j'aimerais bien savoir comment sont trouvées/récupérées les valeurs correspondant aux différents Shifts et Precs...
    Ic Lazarus le traite comme un bitmap 24 bits car le canal alpha est opaque pour tous les pixels (255). Il fait donc une optimisation sur la taille du tampon en mémoire. En effet si tous les pixels sont opaque , pas besoin de gérer la transparence et l'utilisation du canal alpha ne sert a rien au final. Mais ça à le chique d'embrouiller, car c'est bien un bitmap 32 bits qui est exporté par Gimp.

    Le fichier est bien un 32 bits sauf que que c'est dans la façon dont il est encodé XRGB c'est différent de ARGB tout est dans l'algorithme d'encodage "BitFields" seul les masques des composantes de couleurs proviennent des informations contenue dans le bmp. La taille et le décalage sont des données calculées. On peux donc déduire si le BMP est au format XRGB grâce à ces masques et aux données calculées. C'est pour ça que tu peux lire "Nombre de bits utilisés : 24" qui correspond au "Depth" du TRawImage.Description (8+8+8+0=24) et pourtant dans Gimp X8 R8 G8 B8 = 8+8+8+8 = 32

    Bout de code provenant de BZImageFileBMP :

    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
     
    // Fonction gestion Shift, Mask et Taille des composantes dans une couleur au format 32 bits (Integer)
    function CreateBitFieldMask(AShift, APrec: Byte): Cardinal; inline;
    begin
      Result := ($FFFFFFFF shr (32 - APrec)) shl AShift;
    end;
     
    function GetMaskShift(AMask: LongWord): ShortInt; inline;
    begin
      Result := 0;
      while ((AMask and (1 shl Result)) = 0) and (Result < 32) do inc(Result);
      if result = 32 then result:=0;
    end;
     
    function GetMaskSize(AMask: LongWord; AShift:ShortInt): Byte; inline;
     
    begin
      Result := 0;
      while (AShift + Result < 32) and ((AMask and (1 shl (AShift + Result))) <> 0) do Inc(Result);
    end;
     
    function GetMaskDeltaShift(ASize:Byte): Integer; inline;
    begin
      result:=8-ASize;
    end;
     
    function ConvertBitFieldsToBZColor(Const aBitFields : TBZColorBitFields; SrcColor : Integer):TBZColor;
      function GetBitFieldValue(Const Value : LongWord; Mask:LongWord; BitShift, BitSize : Byte):Byte; inline;
      var
        I,v,v2 : Integer;
      begin
          V:=(Value and Mask) Shr BitShift;
          V2:=0;
          I:=8-BitSize; //DeltaShift;
          While I>0 do
          begin
            V2 := V2 or (V Shl I);
            I:=I-BitSize;
          end;
          if I<0 then
            V2 := V2 or (V Shr (-I))
          else
            V2 := V2 or (V Shl I);
          V:= (V2 shl 8) + V2;
          Result:= V; //(V and  255); // ClampByte(V);
        end;
     
     
    begin
      With aBitFields do
      begin
        Result.Red:= GetBitFieldValue(SrcColor,RedMask, RedShift, RedSize);
        Result.Green:= GetBitFieldValue(SrcColor,GreenMask, GreenShift, GreenSize);
        Result.Blue:= GetBitFieldValue(SrcColor,BlueMask, BlueShift, BlueSize);
     
        if (AlphaSize=0) then Result.Alpha:=255
        else Result.Alpha:=GetBitFieldValue(SrcColor,AlphaMask, AlphaShift, AlphaSize);
     
      end;
    end;
     
    .....
     
      If (Compression = BMP_COMPRESSION_BITF) Then
            Begin
              With BitFields Do
              Begin
                If (FHeaderType = bmpht_WindowsV1) or (FHeaderType = bmpht_WindowsV4) or (FHeaderType = bmpht_WindowsV5) Then
                Begin
                  If GapSize1 = 12 Then
                  Begin
                    Size := 12;
                    RedMask := (Memory.ReadLongWord);
                    GreenMask := (Memory.ReadLongWord);
                    BlueMask := (Memory.ReadLongWord);
                    AlphaSize := 0;
                  End
                  Else If GapSize1 = 16 Then
                  Begin
                    Size := 16;
                    RedMask := (Memory.ReadLongWord);
                    GreenMask := (Memory.ReadLongWord);
                    BlueMask := (Memory.ReadLongWord);
                    AlphaMask := (Memory.ReadLongWord);
                  End
                  Else If GapSize1 = 0 Then
                  Begin
                    If (FHeaderType = bmpht_WindowsV4) or (FHeaderType = bmpht_WindowsV5) Then
                    Begin
                      Size := 16;
                      RedMask := GetHeaderRedMask;
                      GreenMask := GetHeaderGreenMask;
                      BlueMask := GetHeaderBlueMask;
                      AlphaMask := GetHeaderAlphaMask;
                    End;
                  End;
                End
                Else    // Version Windows 2 ou 3
                Begin
                  Size := 12;
                  RedMask := GetHeaderRedMask;
                  GreenMask := GetHeaderGreenMask;
                  BlueMask := GetHeaderBlueMask;
                  AlphaSize := 0;
                  AlphaMask := 0;
                  If (FHeaderType > bmpht_WindowsV2) Then
                  Begin
                    Size := 16;
                    AlphaMask := GetHeaderAlphaMask;
     
                  End;
                End;
     
                RedShift := GetMaskShift(RedMask);
                GreenShift := GetMaskShift(GreenMask);
                BlueShift := GetMaskShift(BlueMask);
                AlphaShift := GetMaskShift(AlphaMask);
     
                RedSize := GetMaskSize(RedMask, RedShift);
                GreenSize := GetMaskSize(GreenMask, GreenShift);
                BlueSize := GetMaskSize(BlueMask, BlueShift);
                AlphaSize := GetMaskSize(AlphaMask, AlphaShift);
     
                If AlphaSize > 0 Then //--------------------> C'est ICI QUE TOUT SE JOUE AVEC LE FORMAT XRGB
                Begin
                  // Le Mask Alpha cache-t-il une autre composante de la couleur
                  If (RedMask or GreenMask or BlueMask) and AlphaMask <> 0 Then
                  Begin
                    AlphaMask := 0;
                    AlphaShift := 0;
                    AlphaSize := 0;
                  End;
                End;
              End;
            End;
          End;
        End;
    Voila cela dépend comment est encodé le BMP si tous les pixels sont opaques on peux très bien avoir un masque Alpha identique a la composante Bleu. Et c'est lors du décodage qu'il faut faire attention et ne pas obtenir une valeur alpha erronée. Le format Bmp n'est vraiment pas aussi simple que ça. Il s'est complexifié d'année en année et de version en version.

    Sinon voici deux autres discussions sur le format BMP ici et (la 2eme est un peu moins intéressante)
    • "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

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 717
    Points : 15 094
    Points
    15 094
    Par défaut
    Salut salut ( passé presque toute la matinée sur ce post...)

    Citation Envoyé par BeanzMaster Voir le message
    [...] car c'est bien un bitmap 32 bits qui est exporté par Gimp.
    n'importe comment, on va le voir plus bas...

    Citation Envoyé par BeanzMaster Voir le message
    tout est dans l'algorithme d'encodage "BitFields" seul les masques des composantes de couleurs proviennent des informations contenues dans le bmp.
    et tu trouves ces informations où ? Je tourne et retourne les BitmapFileHeader et BitmatInfoHeader dans tous les sens sans trouver...



    étude du comportement de The Gimp (rien que ça ! [v 2.8.2, ça a peut-être évolué depuis])

    J'ai généré 5 fichiers différents ayant tous la même image 2x2 et une couleur orange (soit rgb 202 69 8, CA 45 08 en hexa) :
    Nom : tailles_fichiers_gimp.png
Affichages : 467
Taille : 20,5 Ko

    Une comparaison à l'éditeur hexa des 2 xrgb montre qu'ils sont strictement identiques, avec un format sur 32 bits, le 1er byte étant à 0. Mais ce n'est pas du rgb ensuite, c'est du bgr ! Donc en vrai du xbgr... Serait-ce l'information visible en plein milieu, @46hex ? Je ne trouve pas cette information dans mes docs.

    Sinon, exporter un fichier 32 bits vers le format rgb supprime le canal alpha et le fichier devient identique à un vrai rgb (image du bas sur la copie des 3 visions hexa).

    Il y a ensuite ici une pure coïncidence, pas de bol, qui fait que 4 pixels à 4 bytes = 16 bytes et 4 pixels à 3 bytes = 12 + 2 fois 2 bytes de padding (en vert) = 16 aussi. D'où le fait (exceptionnel !) qu'un fichier rgb a la même taille qu'un fichier argb, lol !
    Ce qui change, c'est l'intérieur du fichier, à l'adresse 1Chex (en orange) : 18 pour les 24 bits, 20 pour les 32.
    Nom : 3analyses_hexa.jpg
Affichages : 536
Taille : 162,5 Ko

    Maintenant, la structure des données avec un épouvantable piège à l'export :
    Nom : export_gimp.png
Affichages : 481
Taille : 28,2 Ko

    Concernant l'option choisie ARGB, c'est faux ! Dans le fichier on retrouve une structure BGRA.
    Pareil avec l'option dessous qui est XBGR dans la vraie vie.
    Mais pourquoi nous jouent-ils des coups pareils ? Surtout qu'en cliquant sur "Aide" on se prend un message comme quoi "Le fichier d'aide est inexistant"
    Ça + ça :
    Citation Envoyé par BeanzMaster Voir le message
    Sinon voici deux autres discussions sur le format BMP ici et (la 2eme est un peu moins intéressante)
    ça donne juste envie de tout abandonner...
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  12. #12
    Expert confirmé
    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
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Jipété Voir le message
    Salut salut ( passé presque toute la matinée sur ce post...)

    n'importe comment, on va le voir plus bas...
    Même si les données sont encodées sur 3 octets cela reste un fichier 32 bits

    Citation Envoyé par Jipété Voir le message
    et tu trouves ces informations où ? Je tourne et retourne les BitmapFileHeader et BitmatInfoHeader dans tous les sens sans trouver...
    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
     { En-tête BMP Windows V2 (non documenté - Adobe Photoshop)@br
        biSize: LongWord; Taille de l'en-tête  = 52 octets }
      TBZWindowsBMPInfoHeaderV2 = Packed Record   //< Ici Taille 48, biSize est lu avant
        biWidth: Longint;                //< Largeur de l'image en pixels
        biHeight: Longint;               //< Hauteur de l'image en pixels
        biPlanes: Word;                  //< Nombre de Plans de couleur  = 1
        biBitCount: Word;                //< Nombre de bits par pixel
        biCompression: Longword;         //< Type de compression
        biSizeImage: Longword;           //< Taille de l'image  AVEC LE PADDING
        biXPixelsPerMeter: Longint;      //< hoizontal pixels per meter
        biYPixelsPerMeter: Longint;      //< vertical pixels per meter
        biClrUsed: Longword;             //< Nombre de couleurs utilisées (0 = toutes)
        biClrImportant: Longword;        //< Nombre de couleurs importantes (0 = toutes)
        biRedMask: Longword;             //< Masque Couleur Rouge
        biGreenMask: Longword;           //< Masque Couleur Vert
        biBlueMask: Longword;            //< Masque Couleur Bleu
      End;
     
      { En-tête BMP Windows V3 (Adobe Photoshop)@br
        biSize: LongWord; Taille de l'en-tête  = 56 octets  }
      TBZWindowsBMPInfoHeaderV3 = Packed Record  // < Ici Taille 52, biSize est lu avant
        biWidth: Longint;                //< Largeur de l'image en pixels
        biHeight: Longint;               //< Hauteur de l'image en pixels
        biPlanes: Word;                  //< Nombre de Plans de couleur  = 1
        biBitCount: Word;                //< Nombre de bits par pixel
        biCompression: Longword;         //< Type de compression
        biSizeImage: Longword;           //< Taille de l'image  AVEC LE PADDING
        biXPixelsPerMeter: Longint;      //< hoizontal pixels per meter
        biYPixelsPerMeter: Longint;      //< vertical pixels per meter
        biClrUsed: Longword;             //< Nombre de couleurs utilisées (0 = toutes)
        biClrImportant: Longword;        //< Nombre de couleurs importantes (0 = toutes)
        biRedMask: Longword;             //< Masque Couleur Rouge
        biGreenMask: Longword;           //< Masque Couleur Vert
        biBlueMask: Longword;            //< Masque Couleur Bleu
        biAlphaMask: Longword;           //< Masque Couleur Alpha
      End;
     
      { En-tête BMP Windows V4@br
        biSize: LongWord; Taille de l'en-tête  = 108 octets }
      TBZWindowsBMPInfoHeaderV4 = Packed Record   //< Ici Taille 104, biSize est lu avant
        biWidth: Longint;                //< Largeur de l'image en pixels
        biHeight: Longint;               //< Hauteur de l'image en pixels
        biPlanes: Word;                  //< Nombre de Plans de couleur  = 1
        biBitCount: Word;                //< Nombre de bits par pixel
        biCompression: Longword;         //< Type de compression
        biSizeImage: Longword;           //< Taille de l'image  AVEC LE PADDING peut être 0 si pas de compression
        biXPixelsPerMeter: Longint;      //< hoizontal pixels per meter
        biYPixelsPerMeter: Longint;      //< vertical pixels per meter
        biClrUsed: Longword;             //< Nombre de couleurs utilisées (0 = toutes)
        biClrImportant: Longword;        //< Nombre de couleurs importantes (0 = toutes)
        biRedMask: Longword;             //< Masque Couleur Rouge
        biGreenMask: Longword;           //< Masque Couleur Vert
        biBlueMask: Longword;            //< Masque Couleur Bleu
        biAlphaMask: Longword;           //< Masque Couleur Alpha
        biCSType: Longword;              //< Type de l'espace de couleur CIE
        biEndpoints: TBZBMP_CIEXYZCoordTriple; //< "Color space endpoints"
        biGammaRed: Longword;            //< Correction Gamma Rouge
        biGammaGreen: Longword;          //< Correction Gamma Vert
        biGammaBlue: Longword;           //< Correction Gamma Bleu
      End;
     
      { En-tête BMP Windows V5@br
        biSize: LongWord; Taille de l'en-tête  = 124 octets }
      TBZWindowsBMPInfoHeaderV5 = Packed Record  //< Ici Taille 120, biSize est lu avant
        biWidth: Longint;                //< Largeur de l'image en pixels
        biHeight: Longint;               //< Hauteur de l'image en pixels
        biPlanes: Word;                  //< Nombre de Plans de couleur  = 1
        biBitCount: Word;                //< Nombre de bits par pixel
        biCompression: Longword;         //< Type de compression
        biSizeImage: Longword;           //< Taille de l'image  AVEC LE PADDING
        biXPixelsPerMeter: Longint;      //< hoizontal pixels per meter
        biYPixelsPerMeter: Longint;      //< vertical pixels per meter
        biClrUsed: Longword;             //< Nombre de couleurs utilisées (0 = toutes)
        biClrImportant: Longword;        //< Nombre de couleurs importantes (0 = toutes)
        biRedMask: Longword;             //< Masque Couleur Rouge
        biGreenMask: Longword;           //< Masque Couleur Vert
        biBlueMask: Longword;            //< Masque Couleur Bleu
        biAlphaMask: Longword;           //< Masque Couleur Alpha
        biCSType: Longword;              //< Type de l'espace de couleur CIE
        biEndpoints: TBZBMP_CIEXYZCoordTriple; //< "Color space endpoints"
        biGammaRed: Longword;            //< Correction Gamma Rouge
        biGammaGreen: Longword;          //< Correction Gamma Vert
        biGammaBlue: Longword;           //< Correction Gamma Bleu
        biIntent: Longword;              //< "rendering intent"
        biProfileData: Longword;         //< Position des données du profile de couleur
        biProfileSize: Longword;         //< Taille des données du profile de couleur
        biReserved: Longword;            //< Réservé
      End;
    Citation Envoyé par Jipété Voir le message
    étude du comportement de The Gimp (rien que ça ! [v 2.8.2, ça a peut-être évolué depuis])

    J'ai généré 5 fichiers différents ayant tous la même image 2x2 et une couleur orange (soit rgb 202 69 8, CA 45 08 en hexa) :

    Une comparaison à l'éditeur hexa des 2 xrgb montre qu'ils sont strictement identiques, avec un format sur 32 bits, le 1er byte étant à 0. Mais ce n'est pas du rgb ensuite, c'est du bgr ! Donc en vrai du xbgr... Serait-ce l'information visible en plein milieu, @46hex ? Je ne trouve pas cette information dans mes docs.
    Non rien à voir

    Citation Envoyé par Jipété Voir le message
    Sinon, exporter un fichier 32 bits vers le format rgb supprime le canal alpha et le fichier devient identique à un vrai rgb (image du bas sur la copie des 3 visions hexa).

    Il y a ensuite ici une pure coïncidence, pas de bol, qui fait que 4 pixels à 4 bytes = 16 bytes et 4 pixels à 3 bytes = 12 + 2 fois 2 bytes de padding (en vert) = 16 aussi. D'où le fait (exceptionnel !) qu'un fichier rgb a la même taille qu'un fichier argb, lol !
    Ce qui change, c'est l'intérieur du fichier, à l'adresse 1Chex (en orange) : 18 pour les 24 bits, 20 pour les 32.
    Ca c'est le "GapSize" tu te souviens ? regardes le bout de code que j'ai posté hier

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     If GapSize1 = 12 Then
    ...
     If GapSize1 = 16 Then
    Citation Envoyé par Jipété Voir le message
    Maintenant, la structure des données avec un épouvantable piège à l'export :
    Concernant l'option choisie ARGB, c'est faux ! Dans le fichier on retrouve une structure BGRA.
    Pareil avec l'option dessous qui est XBGR dans la vraie vie.
    Mais pourquoi nous jouent-ils des coups pareils ? Surtout qu'en cliquant sur "Aide" on se prend un message comme quoi "Le fichier d'aide est inexistant"
    Effectivement cela porte à confusion. Dans les BMP les données sont toujours en BGR ou BGRA sauf cas spéciaux avec le "BitFields" et pour les versions OS2x

    Citation Envoyé par Jipété Voir le message
    Ça + ça : ça donne juste envie de tout abandonner...
    Non, il faut vraiment être patient. Comme je le disais ce n'est pas un format aussi simple que le GIF, le TGA, PCX et même PNG.
    Juste pour te donner un idée, il m'a fallu un peu de 3 mois pour coder ma solution de chargement des fichiers BMP à grand coup de log et de "showmessage". Et malgré tout ça elle n'est pas viable à 100% mais j'arrive à lire et afficher environ 95/96% de mes fichiers test.
    Ce qui m'as beaucoup aidé ce sont les sources avec BMP-TestSuite et le code de firefox. Le truc sur les qui m'avais faire comprendre les "bitfields" correctement et ben ma foie, elle venais de toi ici

    Voici quelques liens parmi beaucoup d'autres que j'ai lu :

    Informations générales sur le format BMP :

    https://fr.wikipedia.org/wiki/Windows_bitmap
    http://fileformats.archiveteam.org/wiki/BMP
    https://en.wikipedia.org/wiki/BMP_file_format (plus complet que la version française)
    https://delphi.developpez.com/cours/...ra/bitmap2.php
    http://www.alrj.org/docs/formats/bmp/BMP.htm
    http://netghost.narod.ru/gff/graphic...ary/os2bmp.htm
    http://www.drdobbs.com/the-bmp-file-...4409533?pgno=5
    http://www.fileformat.info/format/bmp/egff.htm
    http://www.fileformat.info/format/os2bmp/egff.htm


    Encodage/Decodage :

    https://msdn.microsoft.com/en-us/lib...=vs.85%29.aspx
    https://en.wikipedia.org/wiki/File:BitfieldsSLN.png
    http://netghost.narod.ru/gff/graphics/book/ch09_01.htm
    https://fr.wikipedia.org/wiki/Codage_de_Huffman
    http://tcharles.developpez.com/Huffman/

    Autres informations utiles :

    https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx
    https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx
    https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

    Une chose est sûre si ton comptes passer par les solutions de FPC et Lazarus tu n'arriveras pas à lire beaucoup de fichier correctement. Juste les plus "standard".
    • "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

  13. #13
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 717
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 717
    Points : 15 094
    Points
    15 094
    Par défaut
    Citation Envoyé par BeanzMaster Voir le message
    Même si les données sont encodées sur 3 octets cela reste un fichier 32 bits
    Alors ça, il va falloir me l'expliquer en long en large en travers et en profondeur parce que je ne vois vraiment pas comment c'est possible, dans la mesure où la dénomination 24/32 dépend justement du nombre d'octets.


    Citation Envoyé par BeanzMaster Voir le message
    Ca c'est le "GapSize" tu te souviens ? regardes le bout de code que j'ai posté hier
    Non, je ne me souviens pas, je fais trop de choses dans tous les sens et comme tu n'expliques pas d'où sortent tes GapSize1 et 2, je ne suis pas plus avancé.

    Merci cependant de te décarcasser pour moi, mais quand je vois la montagne de liens que tu donnes, je suis épuisé avant d'en avoir ouvert un seul !

    Citation Envoyé par BeanzMaster Voir le message
    Une chose est sûre si tu comptes passer par les solutions de FPC et Lazarus tu n'arriveras pas à lire beaucoup de fichiers correctement. Juste les plus "standard".
    Hé bien hier tu parlais des voisins, où je suis allé voir, et l'ami J.P a parlé de la dernière de Vampyre (que je croyais en sommeil mais point nenni, la librairie s'est réveillée), tiens, MP for J.P : pas de problème d'ouverture de Tigers.jpg avec LCLimager, trop bien !
    Pour une fois que quelque chose fonctionne du premier coup sous Linux alors que ça coince ailleurs, faut pavoiser
    (Par contre, j'ai souffert avec les chemins pour compiler VCLimageBrowser, n'ayant pas installé le package. Mais je m'en suis sorti, hé hé hé).

    Et cette librairie est capable d'ouvrir un fichier gif trouvé dans les "bad", incroyable parce que si Linux arrive à l'afficher en animation, je n'ai pas de miniature (pareil, c'est J.P qui m'a donné l'idée de l'ouvrir, voir son post) :
    Nom : bad_ou_pas_bad.png
Affichages : 772
Taille : 48,8 Ko

    J'ai recopié f88xxxxxxx avec un nom plus parlant parce que sans miniature, pour savoir qui fait quoi, dur dur.

    Et je vais peut-être creuser cette piste...

    PS : j'ai mis en place la modif que tu indiquais suite à mes SIGSEGV en test dasn mon détournement du GifViewer, problème réglé,
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  14. #14
    Expert confirmé
    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
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Jipété Voir le message
    Alors ça, il va falloir me l'expliquer en long en large en travers et en profondeur parce que je ne vois vraiment pas comment c'est possible, dans la mesure où la dénomination 24/32 dépend justement du nombre d'octets.
    Dans la forme tu as raison. C'est un fichier 32bits car il est définie tel quel dans l'en-tête "biBitCount". Maintenant les données sont codées en 24bits car la masque alpha à la même valeur qu'un autre masque (généralement le bleu) alors qu'il ne le devrait pas l'algorithme "bitfield" fait que si un masque a une taille de zero alors il n'en tient pas compte lors du décodage.
    Au niveau de l'écriture du BMP, dans ce cas, ce masque est mis à "zero" car tous les pixels de l'image sont opaque, on peux donc considérer que les données peuvent être codées sur 24 bits c'est à dire 3 octets. Mais l'en-tête le format du pixel dans les en-têtes reste à 32bits. Je saist c'est relou. "Made in Microsoft" pourquoi faire simple quand on peux compliquer les choses.

    Citation Envoyé par Jipété Voir le message
    Non, je ne me souviens pas, je fais trop de choses dans tous les sens et comme tu n'expliques pas d'où sortent tes GapSize1 et 2, je ne suis pas plus avancé.

    Merci cependant de te décarcasser pour moi, mais quand je vois la montagne de liens que tu donnes, je suis épuisé avant d'en avoir ouvert un seul !
    Pas de soucis, un forum c'est fait pour partager nos connaissances et nos expériences et en plus j'aime ça le partage

    Pour en revenir au GapSize :

    le 1er "GapSize" c'est l'espace perdu entre la palette de couleurs et les données. Le GapSize peut-être égal à 0. Cet espace perdu est présent surtout avec les en-tête Windows 1,4 et 5
    Si la compression est égale à BITFIELD si ce "GapSize" est égal à 12 alors cet espace contient les masques RGBA donc BitCount = 24.
    Si égal à 16 alors cet espace contient les masques RGBA donc BitCount = 32.
    Si ce gapSize est egal à zero alors format par defaut BGRA. Et pour les version 4 et 5 on doit utiliser les masques présents dans l'en-tête.

    Pour le 2eme GapSize lui est placé après les données. Il sert généralement pour les profiles ICC et est présent principalement dans les versions 5

    Nom : BMPfileFormat.png
Affichages : 565
Taille : 18,5 Ko

    Citation Envoyé par Jipété Voir le message
    Hé bien hier tu parlais des voisins, où je suis allé voir, et l'ami J.P a parlé de la dernière de Vampyre (que je croyais en sommeil mais point nenni, la librairie s'est réveillée), tiens, MP for J.P : pas de problème d'ouverture de Tigers.jpg avec LCLimager, trop bien !
    Pour une fois que quelque chose fonctionne du premier coup sous Linux alors que ça coince ailleurs, faut pavoiser
    (Par contre, j'ai souffert avec les chemins pour compiler VCLimageBrowser, n'ayant pas installé le package. Mais je m'en suis sorti, hé hé hé).

    Et cette librairie est capable d'ouvrir un fichier gif trouvé dans les "bad", incroyable parce que si Linux arrive à l'afficher en animation, je n'ai pas de miniature (pareil, c'est J.P qui m'a donné l'idée de l'ouvrir, voir son post) :
    Nom : bad_ou_pas_bad.png
Affichages : 772
Taille : 48,8 Ko

    J'ai recopié f88xxxxxxx avec un nom plus parlant parce que sans miniature, pour savoir qui fait quoi, dur dur.

    Et je vais peut-être creuser cette piste...
    Vampyre est une très bonne bibliothèques pour le support des différents format. Il faudrait que je la teste un de ces quatre. Au fait quel post de JP ?

    Citation Envoyé par Jipété Voir le message
    PS : j'ai mis en place la modif que tu indiquais suite à mes SIGSEGV en test dans mon détournement du GifViewer, problème réglé,
    • "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

  15. #15
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 717
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 717
    Points : 15 094
    Points
    15 094
    Par défaut
    Citation Envoyé par BeanzMaster Voir le message
    Au fait quel post de JP ?
    Rhôôô, c'est même toi qui as donné le lien, jeudi aprème,

    Plus précisément ici.

    Merci pour les précisions. Mon drame, c'est que ce sont des choses que je lis, que je comprends puis que... j'oublie, hélas
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  16. #16
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 717
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 717
    Points : 15 094
    Points
    15 094
    Par défaut
    Hello, world!
    Citation Envoyé par BeanzMaster Voir le message
    Vampyre est une très bonne bibliothèque pour le support des différents formats. Il faudrait que je la teste un de ces quatre.
    Si certains veulent tester cette librairie, les choses se passent dans le dossier code-fd5c101b7948/Demos/ObjectPascal où vous trouverez 8 dossiers de projets (et 1 dossier "Common").

    Sur ces 8, j'ai totalement zappé le FireMonkeyDemo qui s'adresse aux delphistes purs et durs, et pour les autres, mis à part le D3DDemo qui a l'air bien lié à Windows, j'ai réussi à les compiler, en utilisant l'astuce
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    uses
      {$IFDEF MSWINDOWS}
      spécifique à Windows,
      {$ENDIF}
    là où elle était nécessaire, et dans l'ensemble ça baigne.

    Pour SDLDemo je suggère de lancer le programme depuis la ligne de commande, ça permet d'avoir des infos complémentaires.

    Pour VampConvert, je suggère ça, à la toute fin de DemoUnit.PrintUsage (juste cosmétique mais tellement plus agréable) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
      // Iterate over all image data formats and write their names
      WriteLn('  Supported data formats: '); // jpt added "Ln"
      for FmtIter := ifIndex8 to High(TImageFormat) do
      begin
        if Imaging.GetImageFormatInfo(FmtIter, Info) then
          Write(Info.Name, ' ');
      end;
      WriteLn;  // jpt
    end;
    Ensuite, lancer le binaire depuis la ldc sans arguments affichera cet "usage",

    Et pour VCLimageBrowser, j'ai rajouté une checkbox "CheckFit" en haut à droite, modifié les ancres (False, False, True, True),
    Nom : checkfit.png
Affichages : 438
Taille : 6,5 Ko, activé son événement OnClick
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    procedure TMainForm.CheckFitClick(Sender: TObject); // jpt
    begin
      PaintBox.Repaint;
    end;
    et à peine modifié PaintBoxPaint :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      // Scale image to fit the paint box
      if CheckFit.Checked then  // jpt
        R := ImagingUtility.ScaleRectToRect(FImage.BoundsRect, PaintBox.ClientRect)
      else
        R := ImagingUtility.ScaleRectToRect(FImage.BoundsRect, FImage.BoundsRect);
    Très pratique selon l'image.

    c't'à peu près tout,

    Plus qu'à comprendre pourquoi cette somptueuse librairie se prend les pieds dans le tapis des XRGB générés par ce magnifique outil qu'est The Gimp :
    Nom : bad_xrgb.gif
Affichages : 3444
Taille : 107,6 Ko

    EDIT : et d'autant plus dommage que sous Linux, les xrgb sont corrects :
    Nom : linux_xrgb_correct.png
Affichages : 491
Taille : 20,5 Ko
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  17. #17
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 717
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 717
    Points : 15 094
    Points
    15 094
    Par défaut
    Alors voilà, pour essayer d'y voir clair, j'ai généré une image de 1x1 pixel remplie avec mon bel orange, en 24 bits d'abord et que j'ai exporté en rgb.

    Ensuite j'ai rajouté un canal Alpha et j'ai exporté en argb et pendant que j'y étais, j'ai enfin exporté en xrgb.
    Nom : compar_xrgb_(a)rgb.png
Affichages : 504
Taille : 67,2 Ko

    Ce qui saute aux yeux c'est ce 03 à l'adresse 1Ehex dans le fichier xrgb (ce qui correspond à BI_BITFIELDS, on est d'accord), et la présence d'une ligne 30 en plus par rapport aux deux autres fichiers, ligne dont je n'ai pas encore trouvé l'utilité ; on notera que la 1re ligne reporte bien le changement de taille du fichier.


    Ensuite je me suis concentré sur les datas "visibles" puisque Linux affiche le xrgb avec la bonne couleur (ce qui confirme que je ne sais pas à quoi sert la ligne 30), et voilà ce que ça donne :
    Nom : compar_datas.png
Affichages : 452
Taille : 25,5 Ko

    Constatations : il faut se graver dans le marbre et dans le cerveau au fer rouge que ce que tout le monde appelle rgb est en réalité bgr, et il faut le dire, le redire et le répéter encore ! Regardez le haut de l'image, en orange on voit bien les 3 bytes B G R suivis du byte de padding, BGR certifié car pour avoir un bel orange il faut à peine de B donc 08 et beaucoup de R donc CA.

    On retrouve cette règle dessous avec le argb qui N'EST PAS un argb mais bien un bgra, notez le canal Alpha à fond avec FF, tout ça en bleu transparent.

    Et tout en bas la misère du xrgb qui est juste un xbgr, mais j'ai séparé le byte x des 3 autres, il ne participe pas aux datas (j'ai lu quelque part que ça pourrait être un byte de padding avant l'invention du canal Alpha).

    Tout pour compliquer les choses, et ce n'est pas fini ! Un dernier point : toutes les datas commencent ici "sous" la data 02 mais si Vampyre considère le xrbg comme du argb, il devrait nous faire B 00, G 08 et R 45, ce qui ne correspond pas à cette espèce de marron moche vu ce matin (rgb 102 55 53, soit bgrhex 35 39 66).
    Ça me dépasse...
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  18. #18
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 852
    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 852
    Points : 11 285
    Points
    11 285
    Billets dans le blog
    6
    Par défaut
    Salut JP !
    la 1re ligne reporte bien le changement de taille du fichier
    Celle-ci constitue le premier champ du Bitmap Info Header : 108 octets (6Ch) pour un BITMAPV4HEADER (version 4) et 124 (7Ch) pour une BITMAPV5HEADER, la version 5 ajoutant des données de profils ICC.
    ligne 30 en plus par rapport aux deux autres fichiers
    Elle n'est pas en plus : elle est seulement "renseignée"... Ce sont les masques des octets R, G, B, puis A (sans signification ici) à appliquer à un Cardinal pour retrouver chaque canal. Ces octets ne sont pas utilisés dans les 2 premiers fichiers, qui ne sont pas des BI_BITFIELDS.
    En appliquant ces masques, on trouve bien R = CAh, B = 45h et G = 8h, donc ton beau orange.
    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 !

  19. #19
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 717
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 717
    Points : 15 094
    Points
    15 094
    Par défaut
    Bonsoir, Yves,

    et bienvenue au club

    Merci pour ta participation, qui va m'éclairer certains recoins sombres, et m'enfoncer un peu plus par ailleurs...

    Commençons par un point sur lequel je ne suis pas d'accord :
    Citation Envoyé par tourlourou Voir le message
    Citation Envoyé par Jipété Voir le message
    ligne 30 en plus par rapport aux deux autres fichiers,
    Elle n'est pas en plus : elle est seulement "renseignée"... Ce sont les masques des octets R, G, B, puis A (sans signification ici) à appliquer à un Cardinal pour retrouver chaque canal. Ces octets ne sont pas utilisés dans les 2 premiers fichiers, qui ne sont pas des BI_BITFIELDS.
    les deux premiers fichiers ont 8 lignes, le troisième en a 9, il y a donc bien
    Citation Envoyé par Jipété Voir le message
    une ligne 30 en plus par rapport aux deux autres fichiers,
    D'ailleurs,
    Citation Envoyé par tourlourou Voir le message
    108 octets (6Ch) pour un BITMAPV4HEADER (version 4) et 124 (7Ch) pour une BITMAPV5HEADER, la version 5 ajoutant des données
    124-108=16, la longueur de cette ligne en plus
    Ensuite, oui, cette ligne est renseignée avec cette histoire de profils que je creuserai demain (fait trop chaud le soir).

    Citation Envoyé par tourlourou Voir le message
    En appliquant ces masques, on trouve bien R = CAh, B = 45h et G = 8h, donc ton beau orange.
    Faudrait que tu nous expliques comment les appliquer, si t'as deux minutes

    Et ce qui est curieux dans tout ça, c'est que les trois fichiers ont été générés par la même session Gimp depuis la même image : pourquoi a-t-il utilisé un BITMAPV4HEADER pour le argb et un BITMAPV5HEADER pour le xrgb ?
    Un mystère qui complique les choses...

    Et pourquoi Vampyre n'arrive pas à le lire ? Un autre mystère.

    Merci pour le coup de main,
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  20. #20
    Expert confirmé
    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
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Salut,
    Citation Envoyé par Jipété Voir le message
    les deux premiers fichiers ont 8 lignes, le troisième en a 9, il y a donc bien
    D'ailleurs,
    124-108=16, la longueur de cette ligne en plus
    Ensuite, oui, cette ligne est renseignée avec cette histoire de profils que je creuserai demain (fait trop chaud le soir).
    Ce n'est pas le profil ICC c'est le GapSize dont on à parlé plus haut 16 octets = Masque pour RGBA = 1 masque = 4 octets 4x4 = 16

    Citation Envoyé par Jipété Voir le message
    Faudrait que tu nous expliques comment les appliquer, si t'as deux minutes
    C'est dans le code que j'ai mis ici cf function ConvertBitFieldsToBZColor(Const aBitFields : TBZColorBitFields; SrcColor : Integer):TBZColor; Plus jette un oeil sur https://en.wikipedia.org/wiki/BMP_file_format partie Pixel Format.
    Citation Envoyé par Jipété Voir le message
    Et ce qui est curieux dans tout ça, c'est que les trois fichiers ont été générés par la même session Gimp depuis la même image : pourquoi a-t-il utilisé un BITMAPV4HEADER pour le argb et un BITMAPV5HEADER pour le xrgb ?
    Un mystère qui complique les choses...

    Et pourquoi Vampyre n'arrive pas à le lire ? Un autre mystère.
    Bonne question pourquoi Gimp choisi telle ou telle version ?

    Si j'ai bien vu Vampyre gère les BMP jusqu'a la version 4 pas la 5
    • "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

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 6 12345 ... DernièreDernière

Discussions similaires

  1. [DW MX2004] Comment travailler avec Excel?
    Par pierrot10 dans le forum Dreamweaver
    Réponses: 3
    Dernier message: 11/05/2006, 17h34
  2. Comment travailler avec Win32
    Par Mathieu.J dans le forum MFC
    Réponses: 4
    Dernier message: 25/01/2006, 09h49
  3. [XSLT] Comment travailler avec la balise <br/>
    Par billou13 dans le forum XSL/XSLT/XPATH
    Réponses: 3
    Dernier message: 11/10/2005, 10h47
  4. Comment travailler avec le port IEEE 1394?
    Par Cornejito dans le forum MFC
    Réponses: 6
    Dernier message: 04/05/2005, 14h22
  5. Comment travailler avec le client ?
    Par mathieu dans le forum Gestion de projet
    Réponses: 3
    Dernier message: 12/10/2004, 20h56

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