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 :

Un bitmap dont je veux ôter la transparence [Lazarus]


Sujet :

Lazarus Pascal

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 598
    Billets dans le blog
    65
    Par défaut Un bitmap dont je veux ôter la transparence
    Cela fait maintenant une semaine que je suis dessus et je pète un cable je me dis que comme le malade va voir un médecin je trouverais peut-être enfin la solution si je poste le problème

    J'ai un Bitmap avec une couche transparente , quand je veux copier celui-ci dans un autre Bitmap 'virtuel' je voudrait que la transparence soit transformée en une couleur disons par exemple le blanc .
    Pour les plus calés , l'objectif est de supprimer le canal Alpha

    mes tentatives :

    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
     
      ABitMap:=TBitmap.Create;
      try
       ABitmap.Height:=FImage.Bitmap.Height;
       ABitmap.Width:=FImage.Bitmap.Width;
    // ABitmap.PixelsFormat:=pf24bit; 
    // ici j'ai tenté de d'abord remplir l'image à blanc ------ résultat néant
    //   ABitmap.Canvas.Brush.Color:=clwhite;
    //   ABitmap.Canvas.FillRect(0,0,ABitmap.Width,ABitmap.Height);
    // ---------------------------------------------------------------------------------
    // déclaration de blanc comme transparent  avant  
    //   ABitmap.Transparent:=True;
    //   ABitmap.TransparentColor:=clWhite;
    //----------------------------------------------------------------------------------
    // Copie de l'image initiale par Streaming
       memstream := TMemoryStream.create;
       try
        FImage.Bitmap.Transparent:=False;
        FImage.Bitmap.SaveToStream(memstream);
        memstream.position := 0;
        ABitmap.LoadFromStream(memstream);
       finally
         memstream.free;
       end;
    //------------------------------------------------------------------------------------
    // ou par Assign
    // ABitmap.Assign(Fimage.Bitmap);
    //------------------------------------------------------------------------------------ 
    // ABitmap.PixelsFormat:=pf24bit; 
     
      ABitmap.SaveToFile('Copie.Bmp'); // vérification résultat
    Avant de tenter une manipulation plus "lourde" (changement pixel par pixel) quelqu'un aurait-il une idée ?

  2. #2
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 598
    Billets dans le blog
    65
    Par défaut Je me reponds
    C'est bien ce que je signalais au départ , le fait d'aller chez le médecin guérit

    bien que n'ayant pas encore tout compris de la solution ,fortement inspirée de http://wiki.lazarus.freepascal.org/D..._with_Graphics l'exemple de fading , la voici quand même .

    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
     
    uses ...LCLType,      // HBitmap type
               IntfGraphics, // TLazIntfImage type
               fpImage;      // TFPColor type
     
     
    procedure TForm1.Button6Click(Sender: TObject);
    var
       SrcIntfImg, TempIntfImg: TLazIntfImage;
       ImgHandle,ImgMaskHandle: HBitmap;
       px, py: Integer;
       CurColor: TFPColor;
       TempBitmap : TBitmap;
     begin
       SrcIntfImg:=TLazIntfImage.Create(0,0);
       SrcIntfImg.LoadFromBitmap(Image.Bitmap.Handle,Image.Bitmap.MaskHandle);
       TempIntfImg:=TLazIntfImage.Create(0,0);
       TempIntfImg.LoadFromBitmap(Image.Bitmap.Handle,Image.Bitmap.MaskHandle);
       TempBitmap:=TBitmap.Create;
         for py:=0 to SrcIntfImg.Height-1 do begin
           for px:=0 to SrcIntfImg.Width-1 do begin
             CurColor:=SrcIntfImg.Colors[px,py];
             if CurColor.alpha=0 then
              begin
                 if CurColor.red=0 then Curcolor.Red:=clWhite;
                 if CurColor.Green=0 then Curcolor.Green:=clWhite;
                 if CurColor.blue=0 then Curcolor.Blue:=clWhite;
              end;
             TempIntfImg.Colors[px,py]:=CurColor;
           end;
         TempIntfImg.CreateBitmaps(ImgHandle,ImgMaskHandle,false);
         TempBitmap.Handle:=ImgHandle;
         TempBitmap.MaskHandle:=ImgMaskHandle;
         Tempbitmap.SaveTofile('Copie.bmp');
       end;
       SrcIntfImg.Free;
       TempIntfImg.Free;
       TempBitmap.Free;
     end;

  3. #3
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 598
    Billets dans le blog
    65
    Par défaut Ce n'est pas fini
    ce paragraphe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
             if CurColor.alpha=0 then
              begin
                 if CurColor.red=0 then Curcolor.Red:=clWhite;
                 if CurColor.Green=0 then Curcolor.Green:=clWhite;
                 if CurColor.blue=0 then Curcolor.Blue:=clWhite;
              end;
    fonctionne pour ce qui est du blanc (avec un avertissement de debordement )
    maintenant comment mettre une autre couleur ?
    de plus j'ai un doute sur le test curcolor.alpha=0 , admettons que mon 'transparent' soit une autre couleur par exemple clfuchsia comme beaucoup d'icones ?

    je tâtonne , j'ai perdu ma canne blanche, un effort lecteurs , Merci

  4. #4
    Membre émérite
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 79
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 122
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    ce paragraphe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
             if CurColor.alpha=0 then
              begin
                 if CurColor.red=0 then Curcolor.Red:=clWhite;
                 if CurColor.Green=0 then Curcolor.Green:=clWhite;
                 if CurColor.blue=0 then Curcolor.Blue:=clWhite;
              end;
    fonctionne pour ce qui est du blanc (avec un avertissement de debordement )
    Red, Green et Blue sont du type Word alors que clWhite (entre autres couleurs) est du type TColor ...

    EDIT: orthographe

    Cordialement.

    Pierre

  5. #5
    Nouveau membre du Club

    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 8
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    fonctionne pour ce qui est du blanc (avec un avertissement de debordement )
    maintenant comment mettre une autre couleur ?
    de plus j'ai un doute sur le test curcolor.alpha=0 , admettons que mon 'transparent' soit une autre couleur par exemple clfuchsia comme beaucoup d'icones ?
    Le canal alpha va de 0 a 255, 0 invisible, 255 visible
    Il faut que tu change aussi le canal alpha a 255 ou $FFFF dans TLazIntfImage,
    sinon la semi-transparence reste

    Pour les couleurs il y a des fonctions FPColorToTColor et TColorToFPColor si je me rappel bien !!!

  6. #6
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 598
    Billets dans le blog
    65
    Par défaut
    Citation Envoyé par wile64 Voir le message
    Le canal alpha va de 0 a 255, 0 invisible, 255 visible
    Il faut que tu change aussi le canal alpha a 255 ou $FFFF dans TLazIntfImage,
    sinon la semi-transparence reste
    Je vais regarder ça de plus près , mais dans un bitmap c'est sur un seul bit !

    Citation Envoyé par wile64 Voir le message
    Pour les couleurs il y a des fonctions FPColorToTColor et TColorToFPColor si je me rappel bien !!!
    ça va , Aloïs Alzheimer ne te guettes pas encore , j'avais fini par le trouver aussi !

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    64
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 64
    Par défaut
    Bonjour

    Ci-dessous un code source expérimental que j'ai codé à partir de différentes sources sur le net dans le but de vérifier si on pouvait avoir quelque chose d'équivalent à scanline avec Lazarus niveau vitesse.

    C'est le cas.

    Tu peux voir comment accéder/modifier les valeurs RVB en mémoire vive grâce aux pointeurs.
    Par contre le code est ici adapté à des images Bitmap 24Bits (pas de transparence donc)

    A vu de nez je dirais qu'il te faut instancier le RID (Raw Image Description) comme ceci:
    RID.Init_BPP32_B8G8R8A8_BIO_TTB(FWidth,FHeight);
    (consulter la doc freepascal pour être sur...)

    Les déplacements en X ne seraient donc plus de 3 mais de 4:
    24Bits= BVRBVRBVRBVR...
    32Bits= BVRABVRABVRABVRA...

    exemple:

    PLinePByte[X * 4] = Bleu (0..255)
    PLinePByte[X * 4 + 1] = Vert (0..255)
    PLinePByte[X * 4 + 2] = Rouge (0..255)
    PLinePByte[X * 4 + 3] = Alpha (0..255)
    (A tester bien sûr)

    Je n'aime pas trop les conversions de couleur façon freepascal donc j'ai ajouté TSColor (B,V,R,A: Byte([0..255])).

    la procedure TSBitmap.Fill(Color: TSColor) montre comment mélanger 2 couleurs.
    Dans ton cas, pour chaque pixel (x,y) de ton image tu mélange le byte bleu de ta couleur de fond avec le byte bleu du pixel lu en fonction de la valeur du byte alpha du pixel lu, idem pour vert et rouge...

    Il faut ensuite réattribuer les 3 valeurs RVB en mémoire vive à leurs positions respectives en mettant la couche alpha à opaque (0 ou 255, je ne sais plus) avant de tout récupérer de la mémoire vive vers un fichier(ou alors plus simplement attribuer les valeurs rvb (melange couleur de fond + couleurs pixels) dans un TLazIntfImage en 24bits et récupérer ce dernier dans un fichier ou un TBitmap...)

    Note: ceci devrait fonctionner avec des images type png par contre pour ton bitmap, j'ignore comment il est encodé et comment il peut être lu.
    Je crois me souvenir que CopyPixels converti automatiquement l'image de départ dans le format déclaré dans le RID

    Les puristes me corrigeront.

    Bon courage

    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
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
     
     
    unit SBitmap; 
     
    {$mode objfpc}{$H+}
     
    interface
     
    uses
      Classes, SysUtils, FileUtil, LCLProc, LResources, Forms, Controls, Graphics, Dialogs, FileCtrl, StdCtrls, ExtCtrls, ComCtrls,
      IntfGraphics, GraphType, FPImage, LCLType;
     
    type
     
      TSColor =
      packed record
          B: Byte;
          G: Byte;
          R: Byte;
          A: Byte;
      end;
     
     
    type
     
      TSBitmap = class
      private
     
          { private declarations }
     
          // vars
          FWidth: Integer;
          FHeight: Integer;
     
          RID: TRawImageDescription;
     
          // img
          FBitmap: TBitmap;
          FBitmapCore: TLazIntfImage;
          FBitmapTemp: TLazIntfImage;
     
          PLine: Pointer;
          PLinePByte: PByte;
          FLine: Integer;
     
          FColor: TSColor;
     
      public
     
          { public declarations }
     
          // object
          constructor Create;
          destructor Destroy; override;
     
          // load / get bitmap
          procedure LoadBitmap(aBitmap: TBitmap);
          function Bitmap:TBitmap;
     
          // Color
          procedure Fill(Color: TSColor);
      end; 
     
     
     
    implementation
     
    { private declarations }
     
     
    { public declarations }
     
    /////////////////////////////////////////////////////
    // object
    /////////////////////////////////////////////////////
     
     
    constructor TSBitmap.Create;
    begin
     
        FWidth := 10;
        FHeight := 10;
     
        FBitmap := TBitmap.Create;
     
        FBitmapCore := TLazIntfImage.Create(FWidth,FHeight);
        RID.Init_BPP24_B8G8R8_BIO_TTB(FWidth,FHeight);
        FBitmapCore.DataDescription := RID;
     
        FLine := 0;
        PLine := FBitmapCore.GetDataLineStart(FLine);
        PLinePByte := PByte(PLine);
     
    end;
     
     
    destructor TSBitmap.Destroy;
    begin
        FBitmapCore.Free;
        FBitmap.Free;
        inherited;
    end;
     
     
    /////////////////////////////////////////////////////
    // load / get bitmap
    /////////////////////////////////////////////////////
     
     
    procedure TSBitmap.LoadBitmap(aBitmap: TBitmap);
    begin
        FBitmapTemp := TLazIntfImage.Create(0,0);
        FBitmapTemp.LoadFromBitmap(aBitmap.Handle,aBitmap.MaskHandle);
     
        FWidth := FBitmapTemp.Width;
        FHeight := FBitmapTemp.Height;
     
        FBitmapCore.Width := FWidth;
        FBitmapCore.Height := Fheight;
        RID.Init_BPP24_B8G8R8_BIO_TTB(FWidth,FHeight);
        FBitmapCore.DataDescription := RID;
     
        FBitmapCore.CopyPixels(FBitmapTemp);
     
        FLine := 0;
        PLine := FBitmapCore.GetDataLineStart(FLine);
        PLinePByte := PByte(PLine);
     
        FBitmapTemp.Free;
    end;
     
     
    function TSBitmap.Bitmap:TBitmap;
    begin
        FBitmap.Width := FBitmapCore.Width;
        FBitmap.Height := FBitmapCore.Height;
        FBitmapTemp := FBitmap.CreateIntfImage;
        FBitmapTemp.CopyPixels(FBitmapCore);
        FBitmap.LoadFromIntfImage(FBitmapTemp);
        // result
        Result := FBitmap;
        // free
        FBitmapTemp.Free;
    end;
     
     
     
    /////////////////////////////////////////////////////
    // color
    /////////////////////////////////////////////////////
     
     
    procedure TSBitmap.Fill(Color: TSColor);
    var
        X,Y,R,G,B,A,AI: Integer;
    begin
        // alpha
        A := Color.A;
        AI := 255 - A;
        //
        for Y := 0 to FHeight-1 do
        begin
            FLine := Y;
            PLine := FBitmapCore.GetDataLineStart(Y);
            PLinePByte := PByte(PLine);
            for X := 0 to FWidth-1 do
            begin
                // blend
                B := Round(((Color.B*A)+(PLinePByte[X * 3]*AI))/255);
                G := Round(((Color.G*A)+(PLinePByte[X * 3 + 1]*AI))/255);
                R := Round(((Color.R*A)+(PLinePByte[X * 3 + 2]*AI))/255);
                // secure color
                if B < 0 then B := 0;
                if B > 255 then B := 255;
                if G < 0 then G := 0;
                if G > 255 then G := 255;
                if R < 0 then R := 0;
                if R > 255 then R := 255;
                // set new
                PLinePByte[X * 3] := B;
                PLinePByte[X * 3 + 1] := G;
                PLinePByte[X * 3 + 2] := R;
            end;
        end;
    end;
     
     
     
    initialization
     
     
    end.

  8. #8
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 598
    Billets dans le blog
    65
    Par défaut
    tout d'abord merci @yann.m , je vais me pencher serieusement sur ton code


    @Wile64 , pour la couleur c'est bien ça

    code simplifié à l'extrême pour ne montrer que les parties essentielles
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
           BackColor:=TColorToFPColor(clRed);
           RedGreenblue(clred,red,green,blue);
     
             CurColor:=SrcIntfImg.Colors[px,py];
             if CurColor.alpha=0 then
              begin
                curColor.green:=backcolor.green;// ou green shl 8;
                curColor.Red:=backcolor.red;// ou red shl 8;
                curColor.Blue:=backcolor.blue;// ou blue shl 8;
              end;
    ceci fonctionne parfaitement (enfin les tests sous windows) a un détail près hélas . Pour les couleurs que je qualifierais de primaires
    soit clred, clblue ,clwhite etc... pas de soucis par contre un clhotlight,clbtnshadow etc.. me donne du noir

    encore un effort en perspective

    PS. merci a ceux qui ont considérés ce fil très interessant au ppoint de lui mettre 5 etoiles

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

Discussions similaires

  1. Je veux ôter le titre, SVP !
    Par parfait radin dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 26/01/2011, 14h05
  2. transparence de fond d'un bitmap
    Par Archimède dans le forum Composants VCL
    Réponses: 4
    Dernier message: 12/09/2005, 19h10
  3. Rave Report et transparence Bitmap
    Par B-Technix dans le forum Composants VCL
    Réponses: 2
    Dernier message: 09/09/2005, 18h34
  4. Transparence de bitmap
    Par TigreRouge dans le forum MFC
    Réponses: 1
    Dernier message: 02/06/2005, 23h40
  5. Bouton avec bitmap transparent
    Par eag35 dans le forum MFC
    Réponses: 2
    Dernier message: 14/09/2004, 16h15

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