IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Delphi Discussion :

Obtenir la couleur d'un pixel d'un bitmap pf8bit (palette)


Sujet :

Langage Delphi

  1. #1
    DMO
    DMO est déconnecté
    Membre averti
    Avatar de DMO
    Profil pro
    Inscrit en
    Février 2004
    Messages
    290
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 290
    Points : 343
    Points
    343
    Par défaut Obtenir la couleur d'un pixel d'un bitmap pf8bit (palette)
    Bonjour,

    J'ai un bitmap dont le format des pixels est pf8bit. Je souhaite, pour comprendre l'utilisation des palettes, savoir accéder à n'importe quel pixel et obtenir sa couleur (sans utiliser TCanvas).

    Suite à de brêves recherches qui m'ont amené à trouver tout ce qui m'était nécessaire sur le site d'efg2 notamment, ou dans les sources que Nono40 met à diposition, j'ai rapidement et facilement codé la copie pixel par pixel avec scanline d'un bitmap pf8bit à un autre bitmap pf24bit.

    Malheureusement, j'ai remarqué que lorsque la couleur dans le bitmap d'origine est le blanc, je ne récupère non pas du blanc, mais une couleur fausse (généralement du noir, ou du olive, du rouge, du bleu).

    Ayant soupçonné une spécificité des palettes qui m'échappait, j'ai empiriquement trouvé que lorsque je devais rechercher la couleur de la palette à l'indice 255, je devais renvoyer en dur "blanc" (255, 255, 255), et non pas la valeur de la palette à cet indice. J'ai conclu qu'il en était de même pour le noir (indice 0).

    Mais je ne comprends pas pourquoi, et je me demande si ces deux spécificités sont réellement génériquement valables. Avez-vous svp une explication ?

    [XP Pro, D6 Ent, Affichage windows en 32 bits]

    Mon code :
    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
    procedure TForm1.Button1Click(Sender: TObject);
    var
      vX, vY: Integer;
      vSrc: PByteArray;
      vDest: PRGBTripleArray;
      vPalette: TMaxLogPalette;
    begin
      Image1.Picture.Bitmap.PixelFormat := pf8bit;
     
      with Image2.Picture.Bitmap do
        begin
          PixelFormat := pf24bit;
          Width := Image1.Picture.Bitmap.Width;
          Height := Image1.Picture.Bitmap.Height;
        end;
     
      with vPalette do
        palNumEntries := GetPaletteEntries(Image1.Picture.Bitmap.Palette, 0, 255, palPalEntry);
     
      for vY := 0 to Image1.Picture.Bitmap.Height-1 do
        begin
          vSrc := Image1.Picture.Bitmap.ScanLine[vY];
          vDest := Image2.Picture.Bitmap.ScanLine[vY];
     
          for vX := 0 to Image1.Picture.Bitmap.Width-1 do
            if vSrc^[vX] = 0 then
              begin
                vDest^[vX].rgbtRed := 0;
                vDest^[vX].rgbtGreen := 0;
                vDest^[vX].rgbtBlue := 0;
              end
            else
            if vSrc^[vX] = 255 then
              begin
                vDest^[vX].rgbtRed := 255;
                vDest^[vX].rgbtGreen := 255;
                vDest^[vX].rgbtBlue := 255;
              end
            else
              with vPalette.palPalEntry[vSrc^[vX]] do
                begin
                  vDest^[vX].rgbtRed := peRed;
                  vDest^[vX].rgbtGreen := peGreen;
                  vDest^[vX].rgbtBlue := peBlue;
                end;
        end;
    end;
    « La simplicité est la sophistication suprême » (Léonard de Vinci)

  2. #2
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Salut,

    Si mes souvenirs sont bons, il faut que tu fasses attention avec les couleurs de 0 à 9 et de 246 à 255 (donc les 10 premières et les 10 dernières), de la palette d'un bitmap 8bits, étant donnée quelles sont réservées par le système et représentent le 20 couleurs de base Windows (clBlack, clCyan,ClYellow,clRed,clWhite, etc...).

    Elles sont invariantes, tu ne peux pas les changer. Je crois que c'est effectivement expliqué sur le site d'efg.

    Voilà, voilà
    Bidouilleuse Delphi

  3. #3
    DMO
    DMO est déconnecté
    Membre averti
    Avatar de DMO
    Profil pro
    Inscrit en
    Février 2004
    Messages
    290
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 290
    Points : 343
    Points
    343
    Par défaut
    Salut Waskol,

    Merci pour ta réponse.
    En effet tes souvenirs sont parfaitement bons, j'avais effectivement appris sur le site d'efg que certaines couleurs (les 10 premieres, et les 10 dernieres) sont réservées au système pour l'affichage des boutons, etc... (principalement en mode 256 couleurs)

    Il faut donc effectivement faire attention à ne définir que les autres lorsqu'on écrit dans la palette.

    En l'occurence, ça ne résoud pas mon interrogation, puisque je ne souhaite que lire dans la palette, en me servant de l'indice que scanline m'a retourné. Je n'y puis donc rien s'il me retourne un indice qui est dans les couleurs système (on immagine en effet aisément que le blanc est une couleur utilisée par le système). Je ne saisis pas pourquoi le code très simple qui suit, sans les cas particuliers, fonctionne mal (comme décrit dans mon post précédent).

    Pourquoi suis-je obligé de traiter les cas particuliers de l'indice 255 (cf code du permier post) spécifiquement pour pouvoir obtenir convenablement la couleur voulue (et pour l'indice 0 pour le noir ?) ?

    Donc merci à celui ou celle qui pourra éclaircir ce point.

    Code fonctionnant mal pour le blanc (renvoie du noir ou autre...) :
    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
      vX, vY: Integer;
      vSrc: PByteArray;
      vDest: PRGBTripleArray;
      vPalette: TMaxLogPalette;
    begin
      Image1.Picture.Bitmap.PixelFormat := pf8bit;
     
      with Image2.Picture.Bitmap do
        begin
          PixelFormat := pf24bit;
          Width := Image1.Picture.Bitmap.Width;
          Height := Image1.Picture.Bitmap.Height;
        end;
     
      with vPalette do
        palNumEntries := GetPaletteEntries(Image1.Picture.Bitmap.Palette, 0, 255, palPalEntry);
     
      for vY := 0 to Image1.Picture.Bitmap.Height-1 do
        begin
          vSrc := Image1.Picture.Bitmap.ScanLine[vY];
          vDest := Image2.Picture.Bitmap.ScanLine[vY];
     
          for vX := 0 to Image1.Picture.Bitmap.Width-1 do
            with vPalette.palPalEntry[vSrc^[vX]] do
              begin
                vDest^[vX].rgbtRed := peRed;
                vDest^[vX].rgbtGreen := peGreen;
                vDest^[vX].rgbtBlue := peBlue;
              end;
        end;
    end;
    « La simplicité est la sophistication suprême » (Léonard de Vinci)

  4. #4
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Si tu es sous XP et Delphi 7, rajoutes un XPManifest sur ta fiches, LOL

    --> Merci Windows
    Bidouilleuse Delphi

  5. #5
    DMO
    DMO est déconnecté
    Membre averti
    Avatar de DMO
    Profil pro
    Inscrit en
    Février 2004
    Messages
    290
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 290
    Points : 343
    Points
    343
    Par défaut
    Citation Envoyé par DMO
    [XP Pro, D6 Ent, Affichage windows en 32 bits]
    Sous-entendrais-tu que ceci est un "effet de bord" de XP et que l'utilisation d'un XPManifest me permettrait de faire fonctionner normalement le second code que j'ai posté ???
    « La simplicité est la sophistication suprême » (Léonard de Vinci)

  6. #6
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Voui

    Chez moi ça marche
    Bidouilleuse Delphi

  7. #7
    DMO
    DMO est déconnecté
    Membre averti
    Avatar de DMO
    Profil pro
    Inscrit en
    Février 2004
    Messages
    290
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 290
    Points : 343
    Points
    343
    Par défaut
    bin alors ça !
    comme tu dis : --> Merci Windows...

    Et merci à toi Waskol pour cette piste, mais surtout pour le temps que tu as passé sur mon problème.

    J'ai du mal à trouver XPManifest : c'est parce qu'il est en standard avec D7 ?

    Si je ne peux pas l'utiliser avec D6, peux-tu me dire stp qu'est-ce qu'il est censé faire ? Simplement donner le "look XP" à l'application ?
    « La simplicité est la sophistication suprême » (Léonard de Vinci)

  8. #8
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Oui il est standard sur D7, mais pour Delphi 6, tu dois pouvoir trouver ton bonheur avec TThemeManager sur Delphi Gems

    Ca fonctionne sur Delphi 4 à 6
    A+
    Bidouilleuse Delphi

  9. #9
    DMO
    DMO est déconnecté
    Membre averti
    Avatar de DMO
    Profil pro
    Inscrit en
    Février 2004
    Messages
    290
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 290
    Points : 343
    Points
    343
    Par défaut
    Ah ok. XPManifest "c'est comme" ThemeManager.
    Bon je vois ce que c'est alors. Je suppose que comme ThemeManager c'est un aussi composant "drop-and-forget" (avec qques options).

    J'ai donc fait l'essai avec ThemeManager que j'avais déjà d'installé dans mes compos. Mais déception, cela ne corrige pas les mauvaises lectures dans la palette de mon bitmap 8bits et n'interfère aucunement.

    Je veux bien croire volontiers que le XPManifest, lui, corrige cela ... Soit... En tous ca je note que sous D7 et sans XPManifest tu as aussi des lectures incorrectes. Ce qui qqpart me "rassure"...

    Je laisse néanmoins la question initiale ouverte : , au cas ou un spécialiste des bizzarreries windows passerait par là (ceci dit je n'exclus evidemment pas non plus que mon code soit incorrect).

    [je tenterai d'exécuter mon application sur w2k le plus tôt possible par curiosité]

    [EDIT : Application exécutée sous w2k : résultat : même problème.
    Qu'est-ce qui m'échappe dans l'utilisation d'une palette logique windows ? Le blanc et le noir, ou les indices 0 et 255 de la palettes sont ils des cas encore plus particuliers que les cas particuliers des 10 premières et 10 dernières couleurs système ??]
    « La simplicité est la sophistication suprême » (Léonard de Vinci)

  10. #10
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Non, non ton code est correct.

    Tu peux essayer aussi avec le composant TWinXP de chez TMS Software, tu le trouveras ici, et il est aussi gratuit :
    http://www.tmssoftware.com/winxp.htm

    Je l'ai testé, ça marche
    Bidouilleuse Delphi

  11. #11
    DMO
    DMO est déconnecté
    Membre averti
    Avatar de DMO
    Profil pro
    Inscrit en
    Février 2004
    Messages
    290
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 290
    Points : 343
    Points
    343
    Par défaut
    En posant un TWinXP, j'obtiens en effet un changement immédiat : les zones cencées être d'un blanc pur (FFFFFF), qui après copie apparaîssaient noir, apparaîssent à présent parfaitement ... vertes (00FF00) !!!

    Y'a quand meme de quoi devenir , surtout en voyant que le comportement diffère en fonction des système (pour toi ca ne change pas la couleur, ca rend le comportement normal)

    En tous cas tu as soulevé un point crutial : on dirait que c'est un problème lié au système (windows, carte video et pilotes, ... mais pas les histoires de theme à forciori car sous w2k c'est pareil), et non pas à mon code Delphi. Il me restera donc à modifier (au besoin) ce dernier lorsque j'aurais compris le problème avec le système.

    Je cherche à présent dans cette voie et reposerai donc ma question sur le forum windows.

    Merci pour ton aide Waskol.

    À+
    « La simplicité est la sophistication suprême » (Léonard de Vinci)

  12. #12
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut CA Y EST J'AI TROUVE !!!!!!!!!!!!!!!!!!!!!!!!
    CA Y EST J'AI TROUVE !!!!!!!!!!!!!!!!!!!!!!!!


    dans :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    palNumEntries := GetPaletteEntries(Image1.Picture.Bitmap.Palette, 0, 255, palPalEntry);
    Qu'est censé représenter 255 ??? hein, hein, hein ???
    Réponse : le Nombre d'entrées que tu souhaites récupérer et stocker dans ton tableau de couleur n'est ce pas ?

    Or dans une image 8bits, ils y a bien 256 couleurs et non 255 !!! Si tu mets 255, tu ne récupères que les entrées de 0 à 254

    Remplace 255 par 256, LOL.

    Et effectivement, si tu va chercher la couleur à l'index 255 que tu n'as pas récupéré, tu obtiens n'importe quoi

    Et n'oublie pas le tag résolu
    Bidouilleuse Delphi

  13. #13
    DMO
    DMO est déconnecté
    Membre averti
    Avatar de DMO
    Profil pro
    Inscrit en
    Février 2004
    Messages
    290
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 290
    Points : 343
    Points
    343
    Par défaut
    toh !
    Quel c...

    C'est bien trouvé ! (c'est bien ... waskol !) a a a a...

    Me voila rassuré (attention et maintenant le moment de la mauvaise foi : "quand meme ca me choque moins de voir 0, 255 que 0, 256" mais l'api étant fait ainsi il faut que je m'y plie).

    En tous cas c'est super.

    À+
    « La simplicité est la sophistication suprême » (Léonard de Vinci)

  14. #14
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Citation Envoyé par DMO
    Me voila rassuré (attention et maintenant le moment de la mauvaise foi : "quand meme ca me choque moins de voir 0, 255 que 0, 256" mais l'api étant fait ainsi il faut que je m'y plie).
    Quelle mauvaise foi !

    de l'index 0, avec 256 entrées, ça fait bien des entrées de 0 à 255 (de 1 à 255 plus le zéro)
    Bidouilleuse Delphi

  15. #15
    DMO
    DMO est déconnecté
    Membre averti
    Avatar de DMO
    Profil pro
    Inscrit en
    Février 2004
    Messages
    290
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 290
    Points : 343
    Points
    343
    Par défaut
    Je te remercie j'arrive encore à compter , par contre il aurait fallu que je fasse plus attention à ce que représentait ce paramètre, j'avais intuitivement pensé que c'était l'index d'arrivée..., le premier étant l'index de départ. Perdu.
    « La simplicité est la sophistication suprême » (Léonard de Vinci)

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

Discussions similaires

  1. [Débutant] Obtenir couleur d'un pixel
    Par Ywnith dans le forum C#
    Réponses: 5
    Dernier message: 25/01/2013, 13h11
  2. [À télécharger] Obtenir la couleur d'un pixel à l'écran
    Par SfJ5Rpw8 dans le forum Vos téléchargements VB6
    Réponses: 0
    Dernier message: 14/11/2010, 17h50
  3. Réponses: 2
    Dernier message: 14/06/2008, 00h21
  4. Obtenir la couleur d'un pixel d'une PictureBox
    Par avigeilpro dans le forum VB 6 et antérieur
    Réponses: 10
    Dernier message: 30/06/2006, 22h17
  5. Obtenir la couleur d'un pixel
    Par GLDavid dans le forum OpenGL
    Réponses: 2
    Dernier message: 09/03/2004, 18h21

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