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

  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

  9. #9
    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 une petite couche suplémentaire
    Enfin plutôt l'inverse

    maintenant , après test sous linux il me faut aplatir l'image (flatten)



    en effet l'objectif est de passer le bitmap à une 'brosse' canvas.brush
    sous windows , pas de souci ça passe , par contre sous linux pas moyen GRRRRR
    l'image sauvegardée garde au moins une couche , c'est en passant par Gimp que je m'en suis apperçu . Je m'était dans un premier temps focalisé sur la transparence , ce qui semble réglé .

    Attaquons nous aux couches maintenant ! comment tout fusionner ?

  10. #10
    Membre Expert
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 46

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Par défaut
    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 RemoveAlpha(Src, Dest: TBitmap; const GroundColor: TColor);
    begin
      Dest.Width  := Src.width;
      Dest.Height := Src.Height;
      Dest.PixelFormat := pf24bits;
      Dest.canvas.Brush.color := GroundColor;
      Dest.Canvas.FillRect(Dest.Canvas.ClipRect);
      Dest.Canvas.Draw(0,0,Src);
    end;
     
    procedure RemoveAlpha(Src, Dest: TBitmap);
    begin
      Dest.Assign(Src);
      Dest.pixelFormat := pf24bits;
    end;


    séparer les couches d'un bitmap (A, R, G, B):

    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
     
    procedure BitmapExtractBits(Src, Dest: TBitmap; const Mask : longword= $000000FF);
    type
      PPixels = ^TPixels;
      TPixels = packed array[0..0] of LongWord;
    var
      Buffer : TBitmap;
      ppS, ppB : PPixels;
      H, N : integer;
    begin
      if src.pixelFormat <> pf32bits then
        src.pixelFormat := pf32bits;
     
      Buffer := TBitmap.Create;
      try
        Buffer.Width := Src.Width;
        Buffer.Height := Src.Height;
        Buffer.PixelFormat := pf32bits;
        ppS := Src.ScanLine[src.Height-1];
        ppB := Src.ScanLine[Buffer.Height-1];
        H := Buffer.Width * Buffer.Hight - 1;
        for N := 0 to H do
          ppB[N].Color := ppS[N].Color and Mask;
        Dest.Assign(Buffer);
      finally
        Buffer.Free;
      end;
    end;
     
     
    // utilisation :
     
    BitmapExtractBits(BitmapSrc, RedLayer, $000000FF);
    BitmapExtractBits(BitmapSrc, BlueLayer, $00FF0000);
    BitmapExtractBits(BitmapSrc, MagentaLayer, $00FF00FF);
    BitmapExtractBits(BitmapSrc, RGBLayer, $00FFFFFF);

    refusionner les couches :

    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
    procedure BitmapFusion(SrcRed, SrcGreen, SrcBlue, SrcAlpha, Dest : TBitmap);
    type
      PPixels : ^TPixels;
      TPixels : packed array[0..0] of LongWord;
    var
      ppR, ppG, ppB, ppD : PPixels;
      Buffer : TBitmap;
      N, H : integer;
    begin
      Buffer := TBitmap.Create;
      try
        Buffer.Width := SrcRed.Width;
        Buffer.Height:= SrcRed.Heigth;
        Buffer.pixelFormat := pf32bits;
     
        ppD := Buffer.ScanLine[Buffer.Height-1];
        H := Buffer.Width * Buffer.Height -1;
     
        ppR := SrcRed.ScanLine[SrcRed.Height-1];
        ppG := SrcGreen.ScanLine[SrcGreen.Height-1];
        ppB := SrcBlue.ScanLine[SrcBlue.Height-1];
        ppA := SrcAlpha.ScanLine[SrcAlpha.Height-1];
     
        for N := 0 to H do
          ppD[N] := ppR[N] or ppG[N] or ppB[N] or ppA[N];
     
        Dest.Assign(Buffer);
      finally
        Buffer.Free;
      end;
    end;

    EDIT :

    a ben Zut, trop l'habitude de Delphi, il est vrai que Lazarus n'as pas de propriété ScanLine pour TBitmap!
    quel idiot fais-je avec ma solution uniquement fonctionnelle que pour Delphi.
    [ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
    Ma messagerie n'est pas la succursale du forum... merci!

  11. #11
    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 Bien que ...
    Bien qu'ayant appris beaucoup de choses sur les couches et les canaux je me suis aperçu que j'étais sur une fausse piste et que la solution était plus simple (avec l'avantage de fonctionner sous les deux OS principaux Windows et Ubuntu)

    finalement , plutôt que de triturer le canal Alpha , j'ai fusionner un fond avec mon image 'transparente'
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
       ABitmap:=TBitmap.Create;
       ABitmap.SetSize(image.Width,image.Height);
       ABitmap.Canvas.Brush.Color:=Clwhite;  // ou bien sur, la couleur de fond souhaité 
       ABitmap.Canvas.Brush.Style:=bsSolid;
       ABitmap.Canvas.FillRect(Rect(0,0,image.Width,image.Height));     ABitmap.Canvas.StretchDraw(Rect(0,0,image.Width,image.Height),Image.Bitmap);
       ABitmap.SavetoFile('A.bmp');
       ABitmap.Free;

+ 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