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. #21
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 720
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 720
    Points : 15 106
    Points
    15 106
    Par défaut
    Citation Envoyé par BeanzMaster Voir le message
    Bonne question pourquoi Gimp choisit telle ou telle version ?

    Bon, maintenant, peut-être que la dernière version a uniformisé tout ça.

    Citation Envoyé par BeanzMaster Voir le message
    Si j'ai bien vu Vampyre gère les BMP jusqu'à la version 4 pas la 5


    La suite à demain...
    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. #22
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 629
    Points : 10 554
    Points
    10 554
    Par défaut
    Citation Envoyé par Jipété Voir le message
    tout le monde appelle rgb est en réalité bgr
    J'ai travaillé en C++ avec la VCL/ Embarcadero Xe et c'est la même chose.

    Le problème du truc c'est que le format BMP a été inventé dans les années 90 avec la notion de palette de couleurs sur des systèmes 16 bits, pour évoluer avec un canal de transparence, abandon des palettes, un rien de compression etc.
    Il me semble aussi que le stockage de l'image est inversé avec des lignes multiples de 4 : il est unique ce format
    Et au passage, on remercie Microsoft d'avoir fournit/ autorisé des outils qui sont tolérants aux erreurs
    Si la version 5 n'est pas utilisée c'est parce qu'elle ne sert à rien (ajout des profils ICC) .. si à augmenter le nombre de fonctionnalités et la complexité des "compatibles/ incompatibles"

    Et pour revenir au bgr cela vient des processeurs Intel qui lisent les mots de 16 bits poids faible/poids fort (little endian)

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 720
    Points : 15 106
    Points
    15 106
    Par défaut
    Bonjour,
    Citation Envoyé par Jipété Voir le message
    La suite à demain...
    Désolé, j'avais donc prévu de travailler sur les différents BitmapInfoHeaders et j'ai fait complètement autre chose : j'ai creusé en profondeur dans les entrailles du Vampyre , et je commence à cerner le bug...

    D'abord, dans ImagingCanvases, tout en bas, on peut lire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class function TFastARGB32Canvas.GetSupportedFormats: TImageFormats;
    begin
      Result := [ifA8R8G8B8];
    end;
    et dans le Main.LoadFile de VCLimageBrowser on trouve
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    // 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;
    Est-ce qu'il n'aurait pas été plus simple d'écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    // Convert image to 32bit ARGB format 
    FImage.Format := ifA8R8G8B8;
    et basta ?
    Puisqu'in fine c'est ce qu'on retrouve tout au long du pas-à-pas à cause de ImagingBitmap ligne 431 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      case BI.BitCount of
        ...
        32: Format := ifA8R8G8B8; // As with R5G5B5 there is alpha check later <<< ici avec fichier xrgb
      end;
    Ayant constaté ligne 493
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
      case BI.Compression of
        BI_RGB : LoadRGB;
        BI_RLE4: LoadRLE4;
        BI_RLE8: LoadRLE8;
        BI_BITFIELDS: LoadRGB; // <<< on passe ici avec fichier xrgb
      end;
    puis découvert ça ligne 513 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    // Check if there is alpha channel present in A8R8G8B8 images, if it is not
    // change format to X8R8G8B8
    if not Has32BitImageAlpha(Width * Height, Bits) then
      Format := ifX8R8G8B8;
    Je trouve cette première ligne de commentaire un peu idiote puisque, par définition et par construction, le format A8R8G8B8 inclut un canal alpha.
    Tests avec Gimp : image 1x1 à 100% de transparence, les 4 bytes sont à 0, le viewer affiche un carré noir ; image à 99% de transparence, le pixel est à 08 45 CA 02, limite invisible dans le viewer.

    Le test pour les curieux, ligne 2180 :
    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
    function Has32BitImageAlpha(NumPixels: LongInt; Data: PLongWord): Boolean;
    var
      I: LongInt;
    begin
      Result := False;
      for I := 0 to NumPixels - 1 do
      begin
        if Data^ >= 1 shl 24 then
        begin
          Result := True; <<< ici dès I = 0 
          Exit;
        end;
        Inc(Data);
      end;
    end;
    en français : si on décale le pixel 0845CAFF de 24 bits vers la gauche on va se retrouver avec FFxxxxxxxx, correct ?
    Et donc Data^ sera > à 1, on est d'accord.
    Sauf que c'est idiot car si fichier xrgb, les 32 bits sont 000845CA et donc le décalage de 24 bits vers la gauche donne CAxxxxxx et Data^ est encore > à 1,

    j'ai tenté un truc de malade, pour voir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    //jpt        if not Has32BitImageAlpha(Width * Height, Bits) then
            if BI.Compression = BI_BITFIELDS then
              Format := ifX8R8G8B8;
    et là ça l'inscrit dans les infos de l'ihm :
    Nom : xrgb_bad_color.png
Affichages : 346
Taille : 6,5 Ko

    Mais la couleur c'est toujours pas ça...

    Je vous passe les recherches dans les tréfonds d'Imaging, ImagingComponents, ImagingFormats, etc, force est de constater qu'il doit y avoir une conversion quelque part car quand on voit ça, ligne 485 dans imagingComponents :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function PixelFormatToDataFormat(Format: TPixelFormat): TImageFormat;
    begin
      case Format of
        pf8bit: Result := ifIndex8;
        pf15bit: Result := ifA1R5G5B5;
        pf16bit: Result := ifR5G6B5;
        pf24bit: Result := ifR8G8B8;
        pf32bit: Result := ifA8R8G8B8; // et le ifX8... alors !?
      else
        Result := ifUnknown;
      end;
    end;
    on se dit que ça ne peut pas être au top !

    La solution a l'air de se cacher dans Main.TMainForm.PaintBoxPaint, dans les commentaires tout en bas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      // Draw image to canvas (without conversion) using OS drawing functions.
      // Note that DisplayImage only supports images in ifA8R8G8B8 format so
      // if you have image in different format you must convert it or
      // create standard TBitmap by calling ImagingComponents.ConvertImageToBitmap
      ImagingComponents.DisplayImage(PaintBox.Canvas, PaintBox.BoundsRect, FBack);
    Alors j'ai tenté, dans le Main.LoadFile,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
          // Activate first image and update UI
          FImage.ActiveImage := 0;
          SetSupported;
          FImage.ConvertImages(ifX8R8G8B8);// jpt pour voir mais pas mieux
          // pas-à-pas montre que l'image est déjà au format X8...
          // En enlevant le hack ligne 515 de ImagingBitmap,
          // le test montre que src et dst sont différents, ok, mais couleur pas bonne
          // j'ai peur que ce format X8 ne soit pas bon en mémoire...
          PaintBox.Repaint;
    car la conversion se résume, dans ImagingFormats ligne 2914, à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
        for I := 0 to NumPixels - 1 do
        begin
          // general ARGB conversion
          ChannelGetSrcPixel(Src, SrcInfo, Pix64);
          ChannelSetDstPixel(Dst, DstInfo, Pix64);
          Inc(Src, SrcInfo.BytesPerPixel);
          Inc(Dst, DstInfo.BytesPerPixel);
        end;
    et il n'y a rien pour prendre en compte la promenade du canal Alpha de la dernière place dans les pixels ifA8R8G8B8 à la première place dans les pixels ifX8R8G8B8,

    Terminé
    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. #24
    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,

    Une belle prise de tête se format BMP comme l'a dit foetus. L'introduction de l'encodage avec "BitField" c'est une misère à gérer. Imagine qu'il existe des fichier BMP 32 bits décris comme cela A2R10G10B10, A4R8G12B8, ou encore A0R11G11B10 (cf BMP-TestSuite dossier Q) En gros tu peux choisir le nombre de bit que tu veux utilisé par canal à l'enregistrement. Merci Microsoft

    Pour ma part pour différencié un "XRGB / BGRX" a un "ARGB / BGRA" je lis les données normalement. Je teste juste si toute l'image est transparente ou pas pour des raisons d'affichage évidente

    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
    pf32Bits:  // Pas de compression, formats couleurs suivant "BitField" sinon format couleur par defaut BGRA
        Begin
          LineBuffer := nil;
          GetMem(LineBuffer, FRowSize);
          Try
            Y := 0;
            Repeat
              Memory.Read(LineBuffer^, FRowSize);
              If TopDown Then  YY := Y Else YY := MaxHeight - Y;
              DstLine := GetScanLine(YY);
              SrcPtr := PLongWord(LineBuffer);
              X:= Width;
              While (X>0) Do
              Begin
                SrcColor := SrcPtr^;
                DstColor := ConvertBitFieldsToBZColor(ImageDescription.BitFields, SrcColor); //---> Note : Avec un format XRGB la valeur alpha sera toujours égale à FF
                FIgnoreAlpha := FIgnoreAlpha and (DstColor.alpha = 0); // ----> On teste tous les pixels sont 100% transparent 
                DstLine^ := DstColor;
                Inc(SrcPtr);
                Inc(DstLine);
                Dec(X);
              End;
              Inc(Y);
              AdvanceProgress(Delta,0,1,False);
            Until (Y > MaxHeight);
          Finally
            FreeMem(LineBuffer);
            LineBuffer := nil;
          End;
     
          // Si tous les pixels sont transparent, on ignore la transparence pour l'affichage car si non, rien ne serait affiché
          If FIgnoreAlpha Then
          Begin
            ImageDescription.HasAlpha := False; 
            With ImageDescription.BitFields Do
            Begin
              AlphaSize := 0; 
            End;
          End;
    Ensuite pour différencier un format "XRGB / BGRX" du "ARGB / BGRA" je me base sur les valeurs du "BitField" dans ma description de l'image

    Nom : 2018-07-15_142923.jpg
Affichages : 367
Taille : 23,7 Ko

    EDIT : Par contre là j'ai un bug d'affichage de la valeur des masques
    • "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. #25
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 720
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 720
    Points : 15 106
    Points
    15 106
    Par défaut
    Citation Envoyé par BeanzMaster Voir le message
    Une belle prise de tête se format BMP comme l'a dit foetus. L'introduction de l'encodage avec "BitField" c'est une misère à gérer. Imagine qu'il existe des fichier BMP 32 bits décris comme cela A2R10G10B10, A4R8G12B8, ou encore A0R11G11B10 (cf BMP-TestSuite dossier Q) En gros tu peux choisir le nombre de bit que tu veux utiliser par canal à l'enregistrement. Merci Microsoft
    Au secours ! Non mais allô quoi

    Citation Envoyé par BeanzMaster Voir le message
    Ensuite pour différencier un format "XRGB / BGRX" du "ARGB / BGRA" je me base sur les valeurs du "BitField" dans ma description de l'image
    Ben moi je vais sans doute écrire à l'auteur de Vampyre car mettre les mains dedans, c'est un coup à y laisser les doigts et tout le bras ! Dis-toi que dans ses conversions il passe par du 64 bits, si si !

    Bon, bref, j'ai trouvé une manière extrêmement bourrin de récupérer la bonne couleur d'un xrgb, attention, à ne pas mettre en prod, c'est juste pour vérifier qu'en lui passant un bel orange je récupère bien enfin un bel orange :
    Dans ImagingFormats, ligne 2517, ChannelSetDstPixel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
      case DstInfo.BytesPerPixel of
        4:
          with PColor32Rec(Dst)^ do
          begin
    {en faisant ça la couleur est enfin ok !
            A := MulDiv(PixW.A, 255, 65535);
            R := MulDiv(PixW.R, 255, 65535);
            G := MulDiv(PixW.G, 255, 65535);
            B := MulDiv(PixW.B, 255, 65535);        }
            R := MulDiv(PixW.A, 255, 65535);
            G := MulDiv(PixW.R, 255, 65535);
            B := MulDiv(PixW.G, 255, 65535);
            A := MulDiv(PixW.B, 255, 65535);
          end;
    Bon, là je plie la machine, il fait trop chaud et j'ai une bouillie de pixels dans les neurones,


    EDIT : Euh, t'es sûr de toi, là ?
    Citation Envoyé par BeanzMaster Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DstColor := ConvertBitFieldsToBZColor(ImageDescription.BitFields, SrcColor); //---> Note : Avec un format XRGB la valeur alpha sera toujours égale à FF
    Regarde mes images, chez moi la valeur "x" (il n'y a pas de valeur "alpha" dans un xrgb ) est égale à 00 !
    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

  6. #26
    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

    EDIT : Euh, t'es sûr de toi, là ?

    Regarde mes images, chez moi la valeur "x" (il n'y a pas de valeur "alpha" dans un xrgb ) est égale à 00 !
    Oui je suis sûre de ma fonction. le format est 32bits mais seul les canaux RGB sont utilisés. Ma valeur de sortie est un pixel en 32 bits donc oui la valeur alpha est bien définie à FF (255)

    Dans function ConvertBitFieldsToBZColor
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     if (AlphaSize=0) then Result.Alpha:=255
        else Result.Alpha:=GetBitFieldValue(SrcColor,AlphaMask, AlphaShift, AlphaSize);
    EDIT : En plus j'ai une double vérification au cas ou suivant le "bitfield"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     FIgnoreAlpha := FIgnoreAlpha and (DstColor.alpha = 0); // ----> On teste tous les pixels sont 100% transparent
    • "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

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 720
    Points : 15 106
    Points
    15 106
    Par défaut
    Citation Envoyé par BeanzMaster Voir le message
    Oui je suis sûr de ma fonction. le format est 32bits mais seuls les canaux RGB sont utilisés.
    Alors comment expliques-tu le fait que j'aie 00 avant les canaux BGR dans mon fichier xrgb ?
    Nom : xrgb.png
Affichages : 343
Taille : 8,5 Ko

    Citation Envoyé par BeanzMaster Voir le message
    Ma valeur de sortie est un pixel en 32 bits donc oui la valeur alpha est bien définie à FF (255)
    J'aimerais bien voir une copie d'écran de l'afficheur hexa montrant la fin du fichier (un peu comme ci-dessus), merci...

    Citation Envoyé par BeanzMaster Voir le message
    Dans function ConvertBitFieldsToBZColor
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     if (AlphaSize=0) then Result.Alpha:=255
    Pi là aussi va falloir m'expliquer comment tu peux rentrer 11111111bin dans un canal dont la taille est à 0
    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

  8. #28
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 857
    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 857
    Points : 11 291
    Points
    11 291
    Billets dans le blog
    6
    Par défaut
    Alors comment expliques-tu le fait que j'aie 00 avant les canaux BGR dans mon fichier xrgb ?
    Le File Header et le Bitmap Info Header nous disent :
    - en 0Ah que ton image XRGB commence en 8Ah (pas en 8Bh !)
    - en 1Eh qu'elle est composée de pixels non compressés = BitFields (03h)
    - dont le codage indiqué en 1Ch est sur 32 bits (20h)
    - les positions des canaux possibles (au maximum 4) sont données par les masques de lecture sur 4 octets à appliquer à un pixel lu pour trouver chaque canal, à partir de 36h, dans l'ordre RGBA selon le schéma
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     // en appliquant les masques au pixel   00 08 45 CA :
     . pour le canal Red, en 36h     ->      00 00 00 FF => R = CAh
     . pour celui  Green, en 3Ah     ->      00 00 FF 00 => G = 45h
     . pour le      Blue, en 3Eh     ->      00 FF 00 00 => B = 08h
     . pour le     Alpha, en 42h     ->      00 00 00 00 => A = 00h // non considéré dans le xrgb
    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 !

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 720
    Points : 15 106
    Points
    15 106
    Par défaut
    Yep !

    Citation Envoyé par tourlourou Voir le message
    Le File Header et le Bitmap Info Header nous disent :
    - en 0Ah que ton image XRGB commence en 8Ah (pas en 8Bh !)
    on est bien d'accord ! Les datas (1 seul pixel de 4 bytes) commencent à 8Ahex par un 00.
    Confirmé par ce petit calcul sur les doigts : Le 7Chex en 0Ehex (le biSize, number of bytes required by the bih structure) correspond à 124dec, soit partir de 0Ehex et aller jusqu'à 89hex, donc les datas commencent bien à 8Ahex par 00, na !
    Nom : xrgb.png
Affichages : 361
Taille : 24,1 Ko
    et la coïncidence (j'adoooore les coïncidences) fait que la valeur 8Ahex dans l'adresse 0Ahex génère une colonne visuelle qui fait que tout en bas de cette colonne passant par 01, 13, une tripotée de 00, et 02, se trouve l'adresse 8Ahex, lol !

    Citation Envoyé par tourlourou Voir le message
    - en 1Eh qu'elle est composée de pixels non compressés = BitFields (03h)
    on est toujours d'accord.

    Citation Envoyé par tourlourou Voir le message
    - dont le codage indiqué en 1Ch est sur 32 bits (20h)
    on ne change pas une équipe qui gagne (en plus je suis d'actualité, même si je ne la suis pas : je la subis ).

    Citation Envoyé par tourlourou Voir le message
    - les positions des canaux possibles (au maximum 4) sont données par les masques de lecture sur 4 octets à appliquer à un pixel lu pour trouver chaque canal, à partir de 36h, dans l'ordre RGBA selon le schéma
    Merci pour cette explication qui me manquait, mais d'où vient-elle ? Surtout ce "(au maximum 4)".

    Juste un point de français pour lequel je ne suis pas d'accord :
    Citation Envoyé par tourlourou Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     . pour le     Alpha, en 42h     ->      00 00 00 00 => A = 00h // non considéré dans le xrgb
    "non considéré", j'aurais dit "non utilisé pour la représentation de l'image".

    Et donc tu me cites et tu réponds dessous, mais ta réponse n'explique pas pourquoi j'ai 00 en 8Ahex quand Jérome dit qu'il a FF.

    Ta réponse a cependant le mérite de préciser/confirmer mes déductions, mon seul regret c'est de ne pas trouver d'où vient cette adresse 36hex où commencent les masques.
    J'ai trouvé : les masques se trouvent juste après la structure BitmatInfoHeader (https://docs.microsoft.com/en-us/win...-tagbitmapinfo), mais la quantité de masques est pifométrique :
    Citation Envoyé par msdn
    The number of entries in the array depends on the values of the biBitCount and biClrUsed members of the BITMAPINFOHEADER structure.
    car dans le fichier qui m'intéresse biBitCount vaut 32 et biClrUsed 0 et qu'est-ce que je fais avec ces deux valeurs ? Nobody knows...

    Alors j'ai cherché, je suis retourné aux sources (https://msdn.microsoft.com/en-us/lib...=vs.85%29.aspx) et là, je suis un peu tombé par terre :
    1. je découvre l'apparition des flags de compression BI_JPEG et BI_PNG ;
    2. le discours sur le format 32 bits par pixel ne dit pas un mot du canal alpha, on dirait qu'il est là (bien obligé, on a 32 bits) mais non utilisé : The bitmap has a maximum of 2^32 colors. If the biCompression member of the BITMAPINFOHEADER is BI_RGB, the bmiColors member of BITMAPINFO is NULL. Each DWORD [A DWORD is a 32-bit unsigned integer, un cardinal, quoi, ou mieux : un RGBQuad] in the bitmap array represents the relative intensities of blue, green, and red for a pixel. The value for blue is in the least [à gauche] significant 8 bits, followed [vers la droite] by 8 bits each for green and red. The high byte in each DWORD is not used [et deviendra le canal Alpha] ;
    3. tu nous parles de 4 masques sur 4 octets, msdn parle de 3 masques : If the biCompression member of the BITMAPINFOHEADER is BI_BITFIELDS, the bmiColors member contains three DWORD color masks that specify the red, green, and blue components, respectively, of each pixel. Each DWORD in the bitmap array represents a single pixel.


    Bon, soyons clair, tout ça est très compliqué alors on va ralentir un peu, je n'ai pas l'intention de refaire une librairie à la Vampyre, je vais me contenter d'essayer de faire en sorte que cette chose ouvre correctement les fichiers xrgb que je lui passe.
    Et ça sera déjà pas mal, j'y vois beaucoup plus clair.
    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. #30
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 857
    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 857
    Points : 11 291
    Points
    11 291
    Billets dans le blog
    6
    Par défaut
    La structure BitmapInfoHeader présente dans le fichier peut être une version étendue. Dans ton xbgr, elle est de version 5 (https://docs.microsoft.com/fr-fr/win...bitmapv5header), plus longue que dans tes 2 autres exemples qui ne sont qu'en version 4.
    la quantité de masques est pifométrique
    Euh ? Non, la phrase de la msdn est relative au nombre de couleurs utilisées pour une palette. Si biClrUsed = 0, ce qui est ton cas, pas de palette et "True Colors" sur l'étendue de la taille de biBitCount (il y a plus de couleurs quand on attribue 8 bits par canal que 2 !)
    le discours sur le format 32 bits par pixel ne dit pas un mot du canal alpha, on dirait qu'il est là (bien obligé, on a 32 bits) mais non utilisé
    Dans la V1 du BMI, oui, sûrement créée à une époque où la transparence n'avait pas été imaginée, à la différence de l'intérêt d'aligner les données sur un nombre pair d'octets. Mais ton BMI est en version 5 et indique bien les 4 masques (pas un de plus) des 4 canaux (en fait, il y a un "canal" X qui est ignoré, composé des bits non codants R, G, B ou A : Nom : BitfieldsSLN.png
Affichages : 380
Taille : 3,0 Ko
    ta réponse n'explique pas pourquoi j'ai 00 en 8Ahex quand Jérome dit qu'il a FF.
    Ma réponse explique pourquoi il y a 00 en 8Ahex. Il pourrait d'ailleurs y avoir n'importe quelle valeur : avec un masque à 00 00 00 00, elle serait ignorée par le lecteur, ce qui est bien la notion du xbgr = R8G8B8A0X8 qui ne définit que 3 canaux sur 32 bits...
    Elle n'explique pas pourquoi Jérôme trouve FF
    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 !

  11. #31
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 629
    Points : 10 554
    Points
    10 554
    Par défaut
    Citation Envoyé par Jipété Voir le message
    biBitCount vaut 32 et biClrUsed 0 et qu'est-ce que je fais avec ces deux valeurs ? Nobody knows...
    C'est trivial pourtant
    • biBitCount c'est le nombre de bits par couleurs : 8, 16, 24, 32
    • biClrUsed c'est le nombre de couleurs dans ta palette (couleur indexée)


    En lisant la documentation, nous avons les limitations ultra-courantes des 2 systèmes de couleurs
    • Ta palette ne peut pas avoir plus de 2^16 couleurs
    • Tes couleurs "vraies" c'est minimum 16 bits de couleurs (donc soit 16, 24 ou 32) plus le monochrome.


    Mais Microsoft sont des "oufs guedin de la vie" : on peut utiliser les 2 systèmes de couleurs en même temps (si je comprends bien la documentation et en oubliant les détails/ "compatibles - incompatibles" )
    Si tes couleurs "vraies" c'est soit 16 soit 24 bits, tu vois qu'il y a un trou avec des couleurs 32 bits. Donc tu peux mettre un index de palette dans le trou : comment que l'algo se débrouille pour savoir si tu veux la couleur vraie ou bien la couleur indexée ? mystère et boule de gomme

  12. #32
    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
    Bonjour,
    Citation Envoyé par tourlourou Voir le message
    La structure BitmapInfoHeader présente dans le fichier peut être une version étendue. Dans ton xbgr, elle est de version 5 (https://docs.microsoft.com/fr-fr/win...bitmapv5header), plus longue que dans tes 2 autres exemples qui ne sont qu'en version 4.

    Euh ? Non, la phrase de la msdn est relative au nombre de couleurs utilisées pour une palette. Si biClrUsed = 0, ce qui est ton cas, pas de palette et "True Colors" sur l'étendue de la taille de biBitCount (il y a plus de couleurs quand on attribue 8 bits par canal que 2 !)

    Dans la V1 du BMI, oui, sûrement créée à une époque où la transparence n'avait pas été imaginée, à la différence de l'intérêt d'aligner les données sur un nombre pair d'octets. Mais ton BMI est en version 5 et indique bien les 4 masques (pas un de plus) des 4 canaux (en fait, il y a un "canal" X qui est ignoré, composé des bits non codants R, G, B ou A :

    Ma réponse explique pourquoi il y a 00 en 8Ahex. Il pourrait d'ailleurs y avoir n'importe quelle valeur : avec un masque à 00 00 00 00, elle serait ignorée par le lecteur, ce qui est bien la notion du xbgr = R8G8B8A0X8 qui ne définit que 3 canaux sur 32 bits...

    Ou la la, bon dur d'expliquer :

    Citation Envoyé par tourlourou Voir le message
    Le File Header et le Bitmap Info Header nous disent :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     . pour le     Alpha, en 42h     ->      00 00 00 00 => A = 00h // non considéré dans le xrgb
    // non considéré dans le xrgb Masque Alpha =00 00 00 00 donc taille taille du masque = 0

    Citation Envoyé par Jipété Voir le message
    Alors comment expliques-tu le fait que j'aie 00 avant les canaux BGR dans mon fichier xrgb ?

    Pi là aussi va falloir m'expliquer comment tu peux rentrer 11111111bin dans un canal dont la taille est à 0
    Ici ce n'est pas 11111111 mais 00111111.

    Citation Envoyé par tourlourou Voir le message
    Elle n'explique pas pourquoi Jérôme trouve FF
    Dans mon fichier j'ai bien 00

    Citation Envoyé par BeanzMaster Voir le message
    Dans function ConvertBitFieldsToBZColor if (AlphaSize=0) then Result.Alpha:=255
    else Result.Alpha:=GetBitFieldValue(SrcColor,AlphaMask, AlphaShift, AlphaSize);
    255 = FF. c'est ma fonction qui retourne FF pas le 00 présent dans le fichier


    Citation Envoyé par foetus Voir le message
    C'est trivial pourtant
    • biBitCount c'est le nombre de bits par couleurs : 8, 16, 24, 32
    • biClrUsed c'est le nombre de couleurs dans ta palette (couleur indexée)


    En lisant la documentation, nous avons les limitations ultra-courantes des 2 systèmes de couleurs
    • Ta palette ne peut pas avoir plus de 2^16 couleurs
    • Tes couleurs "vraies" c'est minimum 16 bits de couleurs (donc soit 16, 24 ou 32) plus le monochrome.
    Pour ce qui est des palettes :

    Normalement un fichier WINDOWS BMP VALIDE 8bits ne peut pas avoir une palette de plus de 256 couleurs., un BMP 1 bits plus de 2 couleurs, un BMP 4 bits plus de 16 couleurs.
    Cependant certain logiciels peuvent avoir avec des bugs dans leurs procedures d'enregistrement du format BMP.
    Certain peuvent enregistrer une palette des couleurs utilisées dans l'image avec les formats 16, 24, 32 bits en effet certains logiciels sauvegardent une palette pouvant servir de référence pour une réduction du nombre de couleur entre autres.
    De même certain fichier peuvent être invalide en indiquant un mauvais nombre de couleur dans la palette.
    If faut donc calculer le GapSize manuellement pour vérifier le nombre d'octets exacte la palette sans oublier de prendre en compte également les données du "bitfield".

    Citation Envoyé par foetus Voir le message
    Mais Microsoft sont des "oufs guedin de la vie" : on peut utiliser les 2 systèmes de couleurs en même temps (si je comprends bien la documentation et en oubliant les détails/ "compatibles - incompatibles" )
    Si tes couleurs "vraies" c'est soit 16 soit 24 bits, tu vois qu'il y a un trou avec des couleurs 32 bits. Donc tu peux mettre un index de palette dans le trou : comment que l'algo se débrouille pour savoir si tu veux la couleur vraie ou bien la couleur indexée ? mystère et boule de gomme
    L'algo utilise toujours les vraies couleurs. La palette comme je le dis plus haut est présente à titre indicatif (pour les BMP 16,24 et 32 bits). Ensuite pour connaitre la valeur de la couleur indexée c'est suivant le "BitField". Le masque inutilisé pour les vraies couleurs pourrai alors peut-être faire référence à l'index suivant sa valeur. J'avoue n'être pas encore tombé sur ce genre de fichier tordu lors de mes tests.
    • "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. #33
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 720
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 720
    Points : 15 106
    Points
    15 106
    Par défaut
    Bonjour et merci à tous pour ces explications pointues.

    Citation Envoyé par BeanzMaster Voir le message
    255 = FF. c'est ma fonction qui retourne FF pas le 00 présent dans le fichier
    Ah, je n'avais pas bien capté ce point, tout s'éclaire donc !

    De mon côté j'ai pas mal avancé :

    La seule manière d'avoir la bonne couleur c'est de bien prendre en compte ifX8... avec, dans ImagingBitmap ligne 431
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
        case BI.BitCount of
          ...
          24: Format := ifR8G8B8;
    //jpt      32: Format := ifA8R8G8B8; // As with R5G5B5 there is alpha check later 
          32:
            if BI.Compression = BI_BITFIELDS 
            then Format := ifX8R8G8B8  // to deal with xrgb
            else Format := ifA8R8G8B8; // As with R5G5B5 there is alpha check later
        end;
    puis d'appeler la conversion vers ifA8... dans Main.TMainForm.LoadFile (rappel : dans Main.TMainForm.PaintBoxPaint on lit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      // Note that DisplayImage only supports images in ifA8R8G8B8 format so
      // if you have image in different format you must convert it or
      // create standard TBitmap by calling ImagingComponents.ConvertImageToBitmap
    )
    avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
          // Activate first image and update UI
          FImage.ActiveImage := 0;
          SetSupported;
          if FImage.Format = ifX8R8G8B8 then FImage.ConvertImages(ifA8R8G8B8); // jpt
          PaintBox.Repaint;
    en ayant pris soin de rajouter un test dans ImagingFormats.ChannelGetSrcPixel pour l'adaptation des bytes :
    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
      case SrcInfo.BytesPerPixel of
        4:
          with Pix do
          if SrcInfo.Format = ifX8R8G8B8 then // jpt -- to deal with xrgb
          // move X_B_G_R (as recorded in file) to B_G_R_A (needed for good display)
          begin
            A := MulDiv(PColor32Rec(Src).B, 65535, 255);
            R := MulDiv(PColor32Rec(Src).A, 65535, 255);
            G := MulDiv(PColor32Rec(Src).R, 65535, 255);
            B := MulDiv(PColor32Rec(Src).G, 65535, 255);
          end else
          begin
            A := MulDiv(PColor32Rec(Src).A, 65535, 255);
            R := MulDiv(PColor32Rec(Src).R, 65535, 255);
            G := MulDiv(PColor32Rec(Src).G, 65535, 255);
            B := MulDiv(PColor32Rec(Src).B, 65535, 255);
          end;
    Et voilà :
    Nom : rgb_a_xrgb.gif
Affichages : 346
Taille : 60,0 Ko
    Les valeurs des ShowMessage viennent de ImagingTypes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    type
      TImageFormat = (
        ifR8G8B8         = 87,
        ifA8R8G8B8       = 88,
        ifX8R8G8B8       = 89,
    Plus qu'à écrire au monsieur,
    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. #34
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 629
    Points : 10 554
    Points
    10 554
    Par défaut
    Je n'arrive pas à comprendre pourquoi tu te prends la tête c'est pourtant simple

    Il faut regarder la compression. 2 valeurs sont importantes : BI_RGB et BI_BITFIELDS. De toute manière, les images 24 et 32 bits ne peuvent pas être compressées et si on oublie les valeurs spécifiques, ce sont les 2 seules possibles.
    Et pire que cela, il faut avoir une version d'entête au moins égale à 3 sinon on n'a pas de transparence (je pense que le masque alpha est ignoré dans le meilleur des cas).

    Et ensuite, si la compression est BI_BITFIELDS, il faut alors lire les masques (parce que sinon il ne sont pas présents dans l'entête) pour savoir s'il y a de la transparence ou pas (masque alpha == 0) et si le canal alpha est en premier ou en dernier.
    La difficulté me semble que les masques sont en "big endian" et le stockage des couleurs en "little endian" (bgra donc) : rien de préciser

  15. #35
    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 foetus Voir le message
    Je n'arrive pas à comprendre pourquoi tu te prends la tête c'est pourtant simple

    Ce qui est simple pour toi ne l'est pas forcément pour l'autre. Arriverais-tu as l'expliquer clairement et simplement pour que l'autre personne comprenne du premier coup ?

    Citation Envoyé par foetus Voir le message
    Il faut regarder la compression. 2 valeurs sont importantes : BI_RGB et BI_BITFIELDS. De toute manière, les images 24 et 32 bits ne peuvent pas être compressées et si on oublie les valeurs spécifiques, ce sont les 2 seules possibles.
    Et non ce ne sont pas les deux seules valeurs possibles tu peux rajouter BI_JPEG, BI_PNG et BI_ALPHABITFIELD (ce dernier n'etant dispo qu'avec des bmp sous WinCE 5.0 et .NET 4.0 et sup)

    Citation Envoyé par foetus Voir le message
    Et pire que cela, il faut avoir une version d'entête au moins égale à 3 sinon on n'a pas de transparence
    Faux un bmp version 1.0 32bits peux très bien contenir des valeurs dont l'alpha n'est pas opaque à 100%

    Citation Envoyé par foetus Voir le message
    (je pense que le masque alpha est ignoré dans le meilleur des cas).
    Comme ici avec le format XRGB mais il existe d'autre cas. Comme par exemple les format 8bits dont les couleurs de la palette sont aux format BGRA. L'alpha est d'ailleurs majoritairement à ZERO (100% Transparent)
    Et il ya bien sûre également les valeurs de BitFields exotiques comme je l'ai décris dans un de mes messages précédents.

    Citation Envoyé par foetus Voir le message
    Et ensuite, si la compression est BI_BITFIELDS, il faut alors lire les masques (parce que sinon il ne sont pas présents dans l'entête) pour savoir s'il y a de la transparence ou pas (masque alpha == 0) et si le canal alpha est en premier ou en dernier.
    Les valeurs des masques ne sont pas forcément présentes. Le format des données par défaut est alors BGR/BGRA. Pour les masques ce qui est vraiment important de calculer ce sont leur taille respective et le décalage en bit.

    Citation Envoyé par foetus Voir le message
    La difficulté me semble que les masques sont en "big endian" et le stockage des couleurs en "little endian" (bgra donc) : rien de préciser
    Les big-endian et little-endian dépendent de la plateforme ou tourne ton application. Dans le cas d'une machine non-intel les données de l'entête devront être convertit. Pour le reste cela n'a pas vraiment d'importance. Enfin presque, tout dépend de comment tu décides d'organiser les données dans "ta gestion des bitmaps".
    • "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

  16. #36
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 629
    Points : 10 554
    Points
    10 554
    Par défaut
    Citation Envoyé par Jipété Voir le message
    tu nous parles de 4 masques sur 4 octets, msdn parle de 3 masques
    C'est normal tu es sur une vieille version et il faut regarder la version 4 (<- lien msdn en anglais) ou la version 5


    Citation Envoyé par BeanzMaster Voir le message
    Arriverais-tu as l'expliquer clairement et simplement pour que l'autre personne comprenne du premier coup ?
    Je le redis 1 fois : une image voire même une vidéo sont assez simple à comprendre avec un peu de connaissance (même si certains algo comme la compression sont hardcore)
    Mais le format BMP est un gloubi-boulga et le témoignage de l'évolution des cartes graphiques

    Et pourtant à la base c'est simple : un format d'image non compressé, ou légèrement avec RLE.


    Citation Envoyé par BeanzMaster Voir le message
    Et non ce ne sont pas les deux seules valeurs possibles tu peux rajouter BI_JPEG, BI_PNG et BI_ALPHABITFIELD (ce dernier n'etant dispo qu'avec des bmp sous WinCE 5.0 et .NET 4.0 et sup)
    BI_ALPHABITFIELD tu oublies parce que spécifique WinCE et d'après la documentation Microsoft n'existe plus (sûrement en compatibilité)

    Et ensuite je me méfie des valeurs BI_JPEG et BI_PNG.
    Faire un jpeg ou un png avec un format bmp quel est l'avantage du truc ?
    Et je suis persuadé qu'il n'y a que la bibliothèque de Microsoft qui puisse faire des bmp valides avec un jpeg/ png.


    Citation Envoyé par BeanzMaster Voir le message
    Faux un bmp version 1.0 32bits peux très bien contenir des valeurs dont l'alpha n'est pas opaque à 100%
    Ce n'est pas ce qui ressort : BI_BITFIELDS -> BITMAPV2INFOHEADER: RGB bit field masks, BITMAPV3INFOHEADER+: RGBA

    Et il y a ambiguïté parce qu'on peut supposer que les formats BITMAPV2INFOHEADER et antérieur ne supportent pas le masque alpha (et ce serait logique si on regarde l'histoire)
    Édit : C'est Jipété qui l'a confirmé. D'après son lien vers la documentation Microsoft, une vieille version de l'entête ne contient aucun masque et n'utilise que la table des couleurs.


    Seuls les outils ferment les yeux et se débrouillent comme ils peuvent lorsqu'ils rencontrent BITMAPCOREHEADER/ BITMAPV1INFOHEADER/ BITMAPV2INFOHEADER et 1 canal alpha.

    Édit : Il n'y a pas ambiguïté parce que seules les versions 4 et 5 existent. Et que la version 3 est une version officieuse d'Adobe.


    Citation Envoyé par BeanzMaster Voir le message
    Comme par exemple les format 8bits dont les couleurs de la palette sont aux format BGRA. L'alpha est d'ailleurs majoritairement à ZERO (100% Transparent)
    Les couleurs indexées sont à part. Elles sont stockées sur 32 bits, mais le canal alpha n'est pas géré (et ce serait logique si on regarde l'histoire)
    Microsoft par contre l'autorise en spécifiant le drapeau "RGBQUAD.rgbReserved" pour les entêtes 4 et 5 ... et en même temps le désapprouve


    The colors in the color table are usually specified in the 4-byte per entry RGBA32 format. The color table used with the OS/2 BITMAPCOREHEADER uses the 3-byte per entry RGB24 format
    ....
    Microsoft does not disallow the presence of a valid alpha channel bit mask[13] in BITMAPV4HEADER and BITMAPV5HEADER for 1bpp, 4bpp and 8bpp indexed color images, which indicates that the color table entries can also specify an alpha component using the 8.8.8.[0-8].[0-8] format via the RGBQUAD.rgbReserved[14] member. However, some versions of Microsoft's documentation disallow this feature by stating that the RGBQUAD.rgbReserved member "must be zero".

    Citation Envoyé par BeanzMaster Voir le message
    Les valeurs des masques ne sont pas forcément présentes. Le format des données par défaut est alors BGR/BGRA. Pour les masques ce qui est vraiment important de calculer ce sont leur taille respective et le décalage en bit.
    Ce qu'il en ressort, c'est que si tu veux les masques il faut mettre la compression à BI_BITFIELDS.

    Et si ton image a des couleurs 32 bits, c'est la seule valeur possible. Parce que BI_RGB ne remplit que 24 bits et le canal alpha n'existe pas. <- Microsoft supporte le canal alpha avec les images 32 bits, compression BI_RGB (format RGBA)

    Seuls les outils ferment les yeux et se débrouillent comme ils peuvent lorsqu'ils rencontrent BI_RGB et 32 bits ou bien BI_BITFIELDS, 24 bits et un canal alpha non vide.

    Édit : d'après Microsoft il n'est pas valide d'avoir en même temps BI_BITFIELDS et 24 bits

    BI_BITFIELDS Specifies that the bitmap is not compressed. The members bV4RedMask, bV4GreenMask, and bV4BlueMask specify the red, green, and blue components for each pixel. This is valid when used with 16- and 32-bpp bitmaps.
    Et donc, c'est assez simple pour distinguer le format ARGB du format RGBA : il faut lire la valeurs des masques, et notamment celui du masque alpha.
    Microsoft précise que les masques ne doivent pas se chevaucher (ce qui est logique)


    Citation Envoyé par BeanzMaster Voir le message
    Les big-endian et little-endian dépendent de la plateforme ou tourne ton application.
    Sauf qu'on parle d'un format de stockage et non pas d'une représentation en mémoire. Si sur ton disque dur tes images sont stockées en bgra, tu vas avoir une différence lorsque tu vas essayer de la lire en argb.

  17. #37
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 629
    Points : 10 554
    Points
    10 554
    Par défaut
    J'ai trouvé

    Les compressions BI_JPEG et BI_PNG ne sont pas faites pour le stockage, mais pour gérer de grosses images couleurs sur des périphériques ayant très peu de mémoire (<- le format bmp est un format avant tout non compressé donc effectivement cela peut faire mal )
    Par exemple, les imprimantes : on crée une surface DIB et on l'envoie au périphérique. Mais il faut que le périphérique supporte ces formats, le bon OS (NT tu oublies), la bonne version des DLLs et utiliser des fonctions spéciales/ spécifiques comme OleLoadPicture.

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 720
    Points : 15 106
    Points
    15 106
    Par défaut
    Yep !

    Citation Envoyé par foetus Voir le message
    Et donc, c'est assez simple pour distinguer le format ARGB du format RGBA : il faut lire la valeurs des masques, et notamment celui du masque alpha.
    Dans tes rêves !

    D'abord il faut savoir où se trouve ce masque alpha et je n'ai pas lu grand chose l'expliquant, à part le post d'Yves hier matin, terriblement confus au demeurant, au niveau des images, où la 1re partie notée BITFIELDS laisserait supposer qu'il faut 4x32 bits pour coder ces masques quand la ligne dessous "Sample Length" montre que 1x32 suffit -- quant à la ligne RBGAX, voilà-t-y pas qu'on découvre un 5e canal !

    Bref, j'essaye de rapporter sur le croquis ce qu'il y a dans mon fichier 1x1x32_xrgb :
    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
     @ data
    36 00
    37 00
    38 00
    39 FF
    3a 00
    3b 00
    3c FF
    3d 00 
    3e 00
    3f FF
    40 00
    41 00
    42 00
    43 00
    44 00
    45 00
    soit 000000FF0000FF0000FF000000000000, en splittant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     000 000FF 0000FF0 000FF000 000000000
    none alpha  green     red      blue
    et on est bien avancé...
    C'est peut-être à l'envers, alors ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     000000000 000FF000 0FF0000 FF000 000
    Bof...
    à l'envers de l'envers ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     000 00000 0000FF0 000FF000 0FF000000
    Insoluble.
    Yves, source du croquis please, peut-être que le texte autour expliquera des choses.



    Citation Envoyé par foetus Voir le message
    Citation Envoyé par Jipété
    tu nous parles de 4 masques sur 4 octets, msdn parle de 3 masques
    C'est normal tu es sur une vieille version et il faut regarder la version 4 (<- lien msdn en anglais) ou la version 5
    Euh, tu ne l'as pas bien lu, alors... Extrait de ton lien, rubrique BitCount chapitre "32" : If the bV4Compression member of the BITMAPV4HEADER is BI_BITFIELDS, the bmiColors member contains three DWORD color masks that specify the red, green, and blue components of each pixel.
    À moins que 3 != three ?

    Et si je regarde la V5, j'en conclus qu'ils ont fait un bête copier-coller de la V4 :
    If the bV5Compression member of the BITMAPV5HEADER is BI_BITFIELDS, the bmiColors member contains three DWORD color masks that [...]
    D'autant plus amusant que la structure en début d'article montre bien DWORD bV5AlphaMask;...

    J'enfonce le clou : une recherche sur la page de bV5RedMask montre 4 occurrences quand bV5AlphaMask n'en montre que 2.
    La conclusion de la conclusion c'est que msdn n'est pas fiable à 100 %, et là, on est très mal !


    Pour en revenir à Vampyre (vous n'êtes pas assis ? Vous devriez...), je me suis amusé à prendre un fichier 1x1x32_argb et à le recopier puis lui faire subir avec l'éditeur hexa le remplacement de BI_RGB en BI_BITFIELD et le remplacement de 08 45 CA FF par 00 08 45 CA et que croyez-vous qu'il arriva ?
    Vampyre (modifié par ma bidouille d'hier) l'affiche avec mon bel orange, par contre Gimp comme le viewer Linux me sortent le marron sale.
    Conclusion : certains utilisent les masques (et rendent mal les couleurs s'ils sont absents) et d'autres non.
    C'est vraiment une pagaille désespérante.

    Pour dire la vérité profonde, je n'ai pas vu grand chose concernant les masques dans Vampyre (ou je suis passé à côté ?).
    Bon, j'ai encore d'autres tests à faire avec cette librairie avant de lui écrire.
    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

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 720
    Points : 15 106
    Points
    15 106
    Par défaut Devoir de vacances
    J'ai bien conscience que ma manière de faire afficher un xrgb avec Vampyre n'est qu'une grosse bidouille, c"était juste pour vérifier que l'outil est capable de me montrer mon bel orange.
    L'ayant vu, je la supprime.

    Je conserve cependant la détection efficace du ifX8R8G8B8 dans ImagingBitmaps ligne 431 avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
        case BI.BitCount of
          ...
    //jpt      32: Format := ifA8R8G8B8; // As with R5G5B5 there is alpha check later 
          32:
            if BI.Compression = BI_BITFIELDS 
            then Format := ifX8R8G8B8 
            else Format := ifA8R8G8B8; // As with R5G5B5 there is alpha check later
        end;
    Si quelqu'un a mieux, qu'il le dise maintenant sinon qu'il se taise à jamais qu'il le dise plus tard,

    Et la bidouille va devoir être remplacée par quelque chose de plus professionnel, dans ImagingFormats ligne 2491 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
        4:
          with Pix do
          if SrcInfo.Format = ifX8R8G8B8 then // jpt -- to deal with xrgb
          begin
            // devoir de vacances : utiliser les masks...
          end else // Format is ifA8R8G8B8
          begin
            A := MulDiv(PColor32Rec(Src).A, 65535, 255);
            R := MulDiv(PColor32Rec(Src).R, 65535, 255);
            G := MulDiv(PColor32Rec(Src).G, 65535, 255);
            B := MulDiv(PColor32Rec(Src).B, 65535, 255);
          end;
    Le support d'étude se résume à cette vision colorée du fichier 1x1x32_xbgr avec
    • en 1Ehex la valeur BI_BITFIELD ;
    • de 36hex à 45hex les 16 bytes des 4 masks (msdn ) ;
    • et tout en bas à partir de 8Ahex la data, dans l'ordre X, B, G, R. (smiley bidon juste pour gérer l'espacement vertical de ces trois lignes -- encore une bidouille, )

    Nom : masks+datas_xbgr.png
Affichages : 346
Taille : 25,7 Ko

    Voili voilou,

    EDIT 1 : une première piste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
        4:
          with Pix do begin
            if SrcInfo.Format = ifX8R8G8B8 then // jpt -- to deal with xrgb
            begin
              // l'idée est de convertir ifX8R8G8B8 vers ifA8R8G8B8 en utilisant les masks
            end; 
            // Format ifA8R8G8B8
            A := MulDiv(PColor32Rec(Src).A, 65535, 255);
            R := MulDiv(PColor32Rec(Src).R, 65535, 255);
            G := MulDiv(PColor32Rec(Src).G, 65535, 255);
            B := MulDiv(PColor32Rec(Src).B, 65535, 255);
          end;
    EDIT 2 : question liminaire : ils servent à quoi, ces masks ?

    Si on lit des pixels de 32 bits à la queue leu leu, d'accord pour retrouver les bytes des couleurs, mais si on lit directement des bytes ?
    Un truc m'échappe, là...

    Parce que quand on travaille avec du RGBQuad par exemple, on travaille en fait avec un uint de 32 bits et si on veut la couleur rouge on précise simplement monRGBQuad.rgbRed, et je suspecte fortement qu'en interne et à bas niveau c'est le système d'exploitation qui fait mumuse avec les masks pour me renvoyer la valeur que je demande, donc à quoi bon en rajouter une couche ?
    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. #40
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 857
    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 857
    Points : 11 291
    Points
    11 291
    Billets dans le blog
    6
    Par défaut
    EDIT 2 : question liminaire : ils servent à quoi, ces masks ?
    Ils indiquent quels bits des 32 codent chaque canal, selon le schéma d'où mon image était extraite).
    Ce n'est pas parce qu'on code les pixels sur 32 bits qu'on a forcément un codage en 4 fois 8 bits... Le format permet de définir une image non compressée (BitFields) dont les pixels sont codés en True Colors sur 32 bits, mais avec des canaux inégaux (par exemple 5 bits pour le rouge et 7 pour le bleu, mais 8 pour le vert ; un canal de transparence sur 4 bits, et 8 bits qui ne servent à rien...). Je pense que la seule limitation des masques est qu'un canal doit être une succession de bits contigus (et encore...). Un canal peut être à cheval sur plusieurs octets : ce ne sont pas des RGBQuad qu'on lit, mais des pixels dont le format particulier est entièrement décrit dans l'entête.
    Pour les masques, l'utilisation est simple : on lit le Cardinal représentant le pixel, on fait un and avec le masque du canal à lire, et un décalage pour le caler sur le poids faible du Cardinal. Au passage, j'imagine mal que masques et pixels aient des endianités différentes !
    Il n'y a que 4 masques définis : A, R, G, B ; le X correspondant à la différence éventuelle, qui reste inexploitée (sauf en stéganographie ?).
    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 !

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

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