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 :

Modification de la palette de couleur d'un TImage


Sujet :

Langage Delphi

  1. #1
    Expert éminent sénior
    Avatar de Guigui_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2002
    Messages
    1 864
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2002
    Messages : 1 864
    Points : 10 067
    Points
    10 067
    Par défaut Modification de la palette de couleur d'un TImage
    J'utilise un TImage pour afficher une image en niveau de gris sur lequel j'aimerai pouvoir afficher des fausses couleurs. Pour cela, j'utilise l'API Windows et la fonction SetDIBColorTable. Le problème, c'est que même en voulant modifier avec une palette en niveau de gris (quand j'appuie sur le bouton), je n'obtiens pas la même image que l'initiale.

    Y aurait-il quelquechose qui m'aurait échappé. Sinon, y-a-t-il moyen de modifier cette palette sans passer par SetDIBColorTable (en restant simple d'utilisation quand même).



    Voilà le code (complet du projet qui est tout simple): il se compose d'une TForm (Form1), d'un TButton (Button1) et d'un TImage (Image1)

    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
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ExtCtrls, jpeg, Menus;
     
    type tagRGBQUAD = packed record
        rgbBlue: Byte;
        rgbGreen: Byte;
        rgbRed: Byte;
        rgbReserved: Byte;
      end;
     
    type
      TForm1 = class(TForm)
        Image1: TImage;
        Button1: TButton;
        procedure FormCreate(Sender: TObject);
        procedure Button1Click(Sender: TObject);
      public
        PaletteNormale:array[byte] of tagRGBQUAD;
      end;
     {$EXTERNALSYM SetDIBColorTable, Extrait de l'unitée Windows}
      function SetDIBColorTable(DC: HDC; p2, p3: UINT; var RGBQuadSTructs): UINT; stdcall;
     
    var
      Form1: TForm1;
     
    implementation
     
     
    function SetDIBColorTable; external 'gdi32.dll' name 'SetDIBColorTable';
    {$R *.dfm}
     
    procedure TForm1.FormCreate(Sender: TObject);
    var
      bmp:TBitmap;
      i:integer;
    begin
        bmp := TBitmap.Create;
        bmp.LoadFromFile('toto.bmp');
        Image1.Picture.bitmap := bmp;
        for i:=0 to 255 do
              begin
              PaletteNormale[i].rgbBlue := i;
              PaletteNormale[i].rgbGreen := i;
              PaletteNormale[i].rgbRed := i;
              end;
    end;
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
        SetDIBColorTable(image1.Canvas.Handle, 0, 256, PaletteNormale);
        image1.Repaint;
    end;
     
    end.

  2. #2
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Salut
    Je pense que cela peut venir du format de ton bmp.
    J'ai essayé avec une image en couleur (256 couleurs) et l'action du bouton a bien passé l'image en nuances de gris...
    Et si je passe cette image en noir et blanc, rien ne se passe ou plutôt la palette reste identique...
    J'attache l'image que j'ai testé pour que tu puisses comparer.

  3. #3
    Expert éminent sénior
    Avatar de Guigui_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2002
    Messages
    1 864
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2002
    Messages : 1 864
    Points : 10 067
    Points
    10 067
    Par défaut
    Effectivement, cela marche avec ton image.
    En ouvrant la mienne, je n'ai pas le même format de pixel. Sur ton image, en visualisant un pixel (sous Paint Shop Pro), j'avais les valeurs RVBO alors que sur mon image, j'ai du RVBI. En passant mon image en niveau de gris (sous Paint Shop Pro), je passe aussi en RVBO (avec aucune modification visuel de l'imageet la mise en couleur refonctionne alors.
    Le paramètre O vaut toujours 255 alors que le I est compris entre 0 et 255. Je n'ai plus qu'à comprendre la signification de ces 2 lettres (et pourquoi aussi quand je sauvegarde mon image j'ai du I et pas du O (si le problème venait bien de là).

    En tout cas, merci bien, ca m'a mis sur la piste.

    Edit: en fait ca ne fonctionne pas tout à fait:
    Les images que j'utilise sont effectivement en RVBO (donc format correct à priori) mais ce sont des images jpeg. Et là, la ce ne fonctionne plus (alors que si mon image était un bitmap, cela marchait). Quand j'assign le jpg au bmp, le format passe automatiquement de RVBO à RVBI (?)
    La fonction FormCreate devient:

    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 TForm1.FormCreate(Sender: TObject);
    var
      jpg:TJPEGImage;
      i:integer;
    begin
        jpg := TJPEGImage.Create();
        jpg.LoadFromFile('toto.jpg');
        Image1.Picture.bitmap.Assign(jpg);
        for i:=0 to 255 do
              begin
              PaletteNormale[i].rgbBlue := i;
              PaletteNormale[i].rgbGreen := i;
              PaletteNormale[i].rgbRed := i;
              PaletteNormale[i].rgbReserved := i;
              end;
    end;
    Edit:
    Bon pour le RVBI, il doit d'agir de la palette système, les 236 pixels donnant un niveau de gris et les 20 derniers étant réservé pour le reste. Maintenant, il n'y a plus qu'à comprendre pourquoi je passe automatiquement du RVBO en RVBI et comment l'en empêcher
    Fichiers attachés Fichiers attachés

  4. #4
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Citation Envoyé par Guigui_
    Maintenant, il n'y a plus qu'à comprendre pourquoi je passe automatiquement du RVBO en RVBI et comment l'en empêcher
    Je n'ai pas Delphi sous la main mais il me semble que le TBitmap a une propriété permettant de spécifier le type de palette. Je pense qu'il faut peut-être spécifier explicitement pour le JPEG qui doit utiliser une palette différente que les bmp qu'on a créés...

    [Edit]
    Extrait de http://membres.lycos.fr/gladir/LEXIQUE/PORTS/INDEX.HTM:
    Le bit 3 est le Bit I du RVBI: Ce bit sélectionne l'intensité de la couleur de bordure pour tous les modes textes en 16 couleurs de la carte CGA et des Super CGA. Toutefois la carte Graphic Solutions en mode graphique 640x200 pixels en 4 couleurs applique ce bit sur la couleur d'arrière plan plutôt que la bordure. Tandis que le mode graphique 640x200 pixels en 2 couleurs des CGA et Super CGA applique tout simplement à la couleur d'affichage des pixels.
    Je ne sais pas si ça peut t'aider Mais c'est tout ce que j'ai pu trouver sur RGBI et rien sur RGBO...

  5. #5
    Expert éminent sénior
    Avatar de Guigui_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2002
    Messages
    1 864
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2002
    Messages : 1 864
    Points : 10 067
    Points
    10 067
    Par défaut
    J'ai trouvé une méthode.
    Je me créé une image .bmp en niveau de gris (palette de 0-255) avec laquelle je vais pouvoir récupérer la palette initiale (avant d'appliquer mes palettes persos). Et chaque fois que j'assigne un jpg à mon TImage, je colle ensuite la cette première palette au TImage puis je pourrai sans problème appliquer mes palettes persos.
    Il doit y avoir moyen de faire ca plus proprement (en se contentant de se créer tout d'abord une HPalette) et peut-être qu'il y a besoin d'affecter une seule fois la palette au TImage

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    procedure TForm1.FormCreate(Sender: TObject);
    var
      jpg:TJPEGImage;
      imgPalette:TBitmap;
      i:integer;
    begin
        jpg := TJPEGImage.Create();
        jpg.LoadFromFile('toto.jpg');
        ImgPalette := TBitmap.Create();
        ImgPalette.LoadFromFile('imgPalette.bmp');
        Image1.Picture.bitmap.Assign(jpg);
        Image1.Picture.bitmap.Palette := CopyPalette(imgPalette.Palette);
        for i:=0 to 255 do
              begin
              PaletteNormale[i].rgbBlue := i;
              PaletteNormale[i].rgbGreen := i;
              PaletteNormale[i].rgbRed := i;
              PaletteNormale[i].rgbReserved := i;
              end;
       jpg.free;
       imgPalette.Free;
    end;

  6. #6
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    C'est dommage que ça fasse bricolage comme ça Il doit certainement y avoir un moyen de spécifier le type de palette...
    Au fait, as-tu reegardé le lien que j'ai mis plus haut? Visiblement le I de RGBI serait l'intensité de la couleur... Autrement dit son Channel Alpha? Et RGBO comme opacity?

  7. #7
    Expert éminent sénior
    Avatar de Guigui_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2002
    Messages
    1 864
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2002
    Messages : 1 864
    Points : 10 067
    Points
    10 067
    Par défaut
    Citation Envoyé par Pedro
    C'est dommage que ça fasse bricolage comme ça Il doit certainement y avoir un moyen de spécifier le type de palette...
    Au fait, as-tu reegardé le lien que j'ai mis plus haut? Visiblement le I de RGBI serait l'intensité de la couleur... Autrement dit son Channel Alpha? Et RGBO comme opacity?
    En fait, le RVBI, c'est la palette Windows avec les 236 pixels pour l'intensité de gris et les 20 réservés pour la palette système (j'ai pu la visualiser entièrement sous Paint Shop) et I me semble est égale à l'intensité exprimé donc sur l'échelle 0-235.
    Ainsi un pixel blanc a des composantes 255, 255, 255, 235

    Je mets Résolu (même s'il me reste à voir comment passer plutôt par la création d'une palette de niveaux de gris)

  8. #8
    Candidat au Club
    Inscrit en
    Novembre 2007
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 3
    Points : 2
    Points
    2
    Par défaut Modification de la palette de couleur d'un TImage
    Le principe pour obtenir une nuance gris des couleurs, c’est de rendre R=G=B.
    Pour cela, en fait la somme des trois spectre et on les divise par trois (c’est le principe de la moyenne). En suite, on remplie ce résultat « M » avec R=G=B=M.
    Comme un bon exemple vaux mieux que mille discours :
    Vous avez besoin d’un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Uses jpeg ;
    Form1 :TForm1 ; 
    Image1 :TImage ;
    Button1 :TButton ;
    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
     
    unit Unit1;
    {Programme créé par gamegenerators (gamegenerators@voila.fr)}
    interface
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ExtCtrls, jpeg;
    type
      TForm1 = class(TForm)
        Image1: TImage;
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
    var
      Form1: TForm1;
    implementation
    {$R *.dfm}
    procedure TForm1.Button1Click(Sender: TObject);
    var
    x,y,n,t,t1,t2,t3,c:integer;
    s,R,G,B:string;
    begin
    {Enlever '//' si vous voulez lire une image}
    //Image1.Picture.LoadFromFile('FichierImage.$$$');
    for x:=0 to Image1.Picture.Bitmap.Width-1 do
    for y:=0 to Image1.Picture.Bitmap.Height-1 do
    begin
    //Extraction de la couleur
    n:=Image1.Picture.Bitmap.Canvas.Pixels[x,y];
    //***
    //Séparation des niveaux des couleurs R-G-B en valeur Hexadécimal
    //*
    s:=IntToHex(n,2);
    B:=copy(s,1,2);
    if (B='') then    {Evité la valeur Vide dans B}
    B:='00';
    //*
    G:=copy(s,3,2);
    if (G='') then    {Evité la valeur Vide dans G}
    G:='00';
    R:=copy(s,5,2);
    if (R='') then    {Evité la valeur Vide dans R}
    R:='00';
    //***
    //Niveau de gris
    t1:=Strtoint('$'+B);
    t2:=Strtoint('$'+G);
    t3:=Strtoint('$'+R);
    //* Calcule du nivau de Gris
    t:=t1+t2+t3;
    t:=Round(t/3);
    c:=Strtoint('$'+IntToHex(t,2)+IntToHex(t,2)+IntToHex(t,2)); {R=G=B}
    //Remarque: *************
    //Vous pouvez jongler avec les nuances tous simplement
    //en choisissant que la couleur que vous voulez garder.
    //Pour Une nuance de Bleu
    //t:=t2+t3; {Modification R&G}
    //t:=Round(t/2);
    //Si vous changer le Dénominateur [2..255], vous obtenez
    //d'autres dérivées de la couleur
    //c:=Strtoint('$'+IntToHex(t1,2)+IntToHex(t,2)+IntToHex(t,2)); {B<>R=G}
    //***********************
    //*
    Image1.Picture.Bitmap.Canvas.Pixels[x,y]:=c; {Pixels avec Nuance de Gris}
    end;
    end;
    end.

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

Discussions similaires

  1. [VBA-E] boite de dialogue palette de couleur
    Par virginie2 dans le forum Macros et VBA Excel
    Réponses: 17
    Dernier message: 02/04/2017, 15h20
  2. Palette de couleur
    Par Tchupacabra dans le forum Access
    Réponses: 10
    Dernier message: 07/12/2005, 10h29
  3. Réponses: 2
    Dernier message: 14/06/2005, 14h36
  4. [MFC] Utilisation d'une palette de couleur
    Par Kevgeii dans le forum MFC
    Réponses: 2
    Dernier message: 01/06/2005, 17h35

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