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

 Delphi Discussion :

Ecrire un texte sur un bitmap avec fond transparent


Sujet :

Delphi

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

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 562
    Points
    3 562
    Par défaut
    Bon, attend un peu...

    Edit1 :
    Voilà la méthode que je te préconise :
    1) créer un bitmap de la taille du "bandeau de texte" que tu va dessiner sur ton image
    2) dessiner ton texte et le fond dans ce bitmap intermédiaire
    3) dessiner ce bitmap intermédiaire en semi-transparence sur l'image

    Je reviens dans qques minutes...

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

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 562
    Points
    3 562
    Par défaut
    Bon, voilà, alors tout d'abord une petite unité
    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
    193
    194
    195
    196
    197
    198
    199
    200
    unit BandeauGraphique;
     
    interface
    uses windows,graphics;
    type
      TAlignementVertical=(alVTop,alVCenter,alVBottom);
      TAlignementHorizontal=(alHLeft,alHCenter,alHRight);
      TJustification=(JustLeft,JustCenter,JustRight);
     
      TParametresTexteMultiligne=record
           RectangleTexteDansBandeau:TRect;
           AlignementHorizontal:TAlignementHorizontal;
           AlignementVertical:TAlignementVertical;
           TextJustification:TJustification;
      end;
     
      TParametresBandeau=record
           RectangleBandeau:TRect;
           CouleurBandeau:TColor;
           Transparence:integer; //(de 0 à 100)
           TexteMultiligne:TParametresTexteMultiligne;
      end;
    Procedure DessineTexte(Texte:string;BitMapDestination:TBitmap;Bandeau:TParametresBandeau);
     
    implementation
    uses Types;
     
    Function TextSize(Phrase : string; Police : TFont = nil) : TPoint;
    var
      DC: HDC;
      X: Integer;
      Rect: TRect;
      C : TBitmap;
    begin
      C := TBitmap.create;
      if police <> nil then  C.canvas.Font := police;
     
        Rect.Left := 0;
        Rect.Top:=0;
        Rect.Right:=0;
        Rect.Bottom:=0;
        DC := GetDC(0);
        C.Canvas.Handle := DC;
        DrawText(C.Canvas.Handle, PChar(Phrase), -1, Rect, (DT_EXPANDTABS or DT_CALCRECT));
        C.Canvas.Handle := 0;
        ReleaseDC(0, DC);
        result.X:=Rect.Right-Rect.Left;
        result.Y:=Rect.Bottom-Rect.Top;
        C.Free;
    end;
     
    //Notre procedure d'affichage de texte multiligne
    procedure DessineTexteMultiligne(AString: string;ACanvas:TCanvas;ARect: TRect;
                           AlignementHorizontal:TAlignementHorizontal;
                           AlignementVertical:TAlignementVertical;
                           TextJustification:TJustification);
    var
      AHeight,AWidth:integer;
      Rect,oldClipRect:TRect;
      ATop,ALeft,H,W:Integer;
      AText:string;
      JustificationDuTexte:Integer;
      MyRgn:HRGN;
    begin
      with ACanvas do
      begin
        Lock;
        AHeight:=ARect.Bottom-ARect.Top;
     
        AWidth:=ARect.Right-ARect.Left;
        //on calcule la taille du rectangle dans lequel va tenir le texte
        W:=TextSize(AString,ACanvas.Font).X;
        H:=TextSize(AString,ACanvas.Font).Y;
     
        //on calcule la position (Haut,Gauche) du rectangle dans lequel va tenir le texte
        //en fonction de l'alignement horizontal et vertical choisi
        ATop:=ARect.Top;
        ALeft:=ARect.Left;
     
     
        case AlignementVertical of
          alVBottom : ATop:=ARect.Bottom-H;
          alVCenter : ATop:=ARect.Top+((AHeight-H) div 2);
          alVTop    : ATop:=ARect.Top;
        end;
     
        case AlignementHorizontal of
          alHLeft  : ALeft:=ARect.Left;
          alHCenter: ALeft:=ARect.Left+(AWidth-W) div 2;
          alHRight : ALeft:=ARect.Right-W;
        end;
     
        //Fin du calcul du rectangle, on met le resultat dans Rect
        Rect:=Bounds(ALeft,ATop,W,H);
     
        //On remplit le rectangle de la zone sinon on voit le texte que delphi à dessiné
        FillRect(ARect);
     
        //On détermine les paramètres de justification à passer à Windows
        case TextJustification of
          JustLeft  : JustificationDuTexte:=DT_LEFT;
          JustCenter: JustificationDuTexte:=DT_CENTER;
          JustRight : JustificationDuTexte:=DT_RIGHT;
        end;
     
        //Si le texte est plus grand que notre zone, on prend cette précaution (Clipping)
        with ARect do MyRgn :=CreateRectRgn(Left,Top,Right,Bottom);
        SelectClipRgn(Handle,MyRgn);
     
        //On dessine le texte
        DrawText(Handle,PChar(AString),-1,Rect,JustificationDuTexte or DT_NOPREFIX or DT_WORDBREAK );
     
        //On a plus besoin de la zone de clipping
        SelectClipRgn(Handle,0);
        DeleteObject(MyRgn);
        Unlock;
      end;
    end;
     
    Procedure DessineTexte(Texte:string;BitMapDestination:TBitmap;Bandeau:TParametresBandeau);
    type
      PRGBTripleArray = ^TRGBTripleArray;
      TRGBTripleArray = array [Byte] of TRGBTriple;
    var
      ABitmap:TBitmap;
      i      :  INTEGER;
      j      :  INTEGER;
      rowRGB1,rowRGB2 :  pRGBTripleArray;
      RedV,BlueV,GreenV:byte;
      rowMixed:  pRGBTripleArray;
      k1,k2:double;
      Arect:TRect;
      AColor1,AColor2:tcolor;
    begin
      ABitmap:=TBitmap.Create;
      try
        //Etape 1 : on créé le bandeau
     
        //Préparation du Bitmap intermédiaire
        with Bandeau.RectangleBandeau do
        begin
          ABitmap.Width:=Right-Left+1;
          ABitmap.Height:=Bottom-Top+1;
          ABitmap.PixelFormat:=pf24bit;
        end;
        with ABitmap.Canvas do
        begin
          Font.Assign(BitMapDestination.Canvas.Font);
          Brush.Color:=Bandeau.CouleurBandeau;
          Brush.Style:=bsSolid;
          Rectangle(0,0,ABitmap.Width,ABitmap.Height);
        end;
     
        //enfin on dessine le Texte
     
        with Bandeau.TexteMultiligne do
        begin
          DessineTexteMultiligne(Texte,ABitmap.Canvas,
                                 RectangleTexteDansBandeau,
                                 AlignementHorizontal,
                                 AlignementVertical,
                                 TextJustification);
     
        end;
        //Etape 2 : Dessin du Bandeau semi-transparent
        k1:=Bandeau.Transparence/100;
        k2:=1-k1;
        AColor1:=BitMapDestination.Canvas.font.Color;
        with Bandeau.RectangleBandeau do
        for j := Top to Bottom do
        begin
          rowRGB1 := ABitmap.Scanline[j-Top];
          rowRGB2 := BitMapDestination.Scanline[j];
          for i := Left to Right do
          begin
             //(ColorToRGB())
             RedV   := round(k1*rowRGB1[i-Left].rgbtRed+k2*rowRGB2[i].rgbtRed);
             GreenV := round(k1*rowRGB1[i-Left].rgbtGreen+k2*rowRGB2[i].rgbtGreen);
             BlueV  := round(k1*rowRGB1[i-Left].rgbtBlue+k2*rowRGB2[i].rgbtBlue);
             AColor2:=ABitmap.Canvas.Pixels[i-Left,j-Top];
             if AColor1<>AColor2
             then begin
                    rowRGB2[i].rgbtRed   := RedV;
                    rowRGB2[i].rgbtGreen := GreenV;
                    rowRGB2[i].rgbtBlue  := BlueV;
                  end
             else begin
                    rowRGB2[i].rgbtRed   := rowRGB1[i-Left].rgbtRed;
                    rowRGB2[i].rgbtGreen := rowRGB1[i-Left].rgbtGreen;
                    rowRGB2[i].rgbtBlue  := rowRGB1[i-Left].rgbtBlue;
                  end;
          end;
      end;
      finally
        ABitmap.Free;
      end;
     
     
    end;
    end.
    Voir La FAQ suivante pour le dessin de texte multiligne :
    http://delphi.developpez.com/faq/?pa...ignedanscanvas


    Puis un exemple :
    vous placez dans une fiche,
    - un Timage,
    - un Tmemo (dans lequel on écrira le message à faire apparaître dans l'image (n'oubliez pas d'en mettre une à la conception)

    Et un bouton codé comme ceci dans son OnClick :
    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
    procedure TForm1.Button1Click(Sender: TObject);
    var Bandeau:TParametresBandeau;
        WBandeau,HBandeau,HImage:integer;
    begin
       with Image1.Picture.Bitmap do
       begin
         //on dessinera le texte en vert et en gras
         Image1.Picture.Bitmap.Canvas.Font.Name:='Arial';
         Image1.Picture.Bitmap.Canvas.Font.Color:=clLime;
         Image1.Picture.Bitmap.Canvas.Font.style:=[fsbold];
     
         //Le bandeau prendra toute la largeur de l'image
         WBandeau:=Image1.Picture.Bitmap.Width;
         //et fera trois lignes de texte de haut
         HBandeau:=3*Image1.Picture.Bitmap.Canvas.TextHeight('H');
         //On récupère la hauteur de la fenètre (on placera le bandeau en bas)
         HImage:=Image1.Picture.Bitmap.Height;
       end;
       with Bandeau do
       begin
         RectangleBandeau:=Rect(0,HImage-HBandeau-1,WBandeau-1,HImage-1);
         CouleurBandeau:=clRed;
         Transparence:=50;
         with TexteMultiligne do
         begin
           RectangleTexteDansBandeau:=Rect(0,0,WBandeau,HBandeau);
           AlignementVertical:=alVCenter;
           AlignementHorizontal:=alHCenter;
           TextJustification:=JustCenter;
         end;
       end;
       DessineTexte(Memo1.Text,Image1.Picture.Bitmap,Bandeau);
       image1.Refresh;
    end;
    ne pas oublier le :
    ...qui va bien

  3. #23
    Membre expérimenté
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    2 477
    Détails du profil
    Informations personnelles :
    Âge : 71
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 2 477
    Points : 1 348
    Points
    1 348
    Par défaut Super de chez super !
    Bonjour à toutes et à tous,

    @ Waskol, excellente solution et très bien documentée en plus, il me reste à l'adapter avec le reste du code.

    Le test avec ton unité est conforme à ma demande, le fond du message est translucide.

    Sauf erreur de ma part, la taille du texte influence la taille du bandeau et peut être génant à l'utilisation, comme tel le texte est petit.

    Encore merci @ Waskol pour cette solution présentée sur un plat d'argent.

    @+,

    Cincap

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

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 562
    Points
    3 562
    Par défaut
    Citation Envoyé par cincap Voir le message
    Sauf erreur de ma part, la taille du texte influence la taille du bandeau et peut être génant à l'utilisation, comme tel le texte est petit.
    Hé oui, erreur, Les dimensions du bandeau son déterminé par
    RectangleBandeau (ce sont les coordonnées relatives à l'image), alors que
    RectangleTexteDansBandeau ce sont les coordonnées du rectangle dans lequel s'inscrit le texte, (coordonnées relatives prises par rapport au bandeau).

    J'ai choisi ici effectivement une hauteur de bandeau en fonction de la taille du texte :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    HBandeau:=3*Image1.Picture.Bitmap.Canvas.TextHeight('H');
    Mais rien ne t'empêche de mettre une valeur fixée de, par exemple, 50 pixels de haut.
    voili voilou...

  5. #25
    Membre expérimenté
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    2 477
    Détails du profil
    Informations personnelles :
    Âge : 71
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 2 477
    Points : 1 348
    Points
    1 348
    Par défaut C'est super, cela fonctionne !
    @ Waskol, Bien voila, ta procédure a été adaptée à mon code et cela fonctionne correctement avec même un redimensionnement de la fonte ainsi que l'accès aux paramètres prédéfinis que l'on peut modifier.

    Encore un grand merci pour cette solution prête à l'emploi. .

    Bon week-end à toutes et à tous,

    @+,

    Cincap

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Réponses: 1
    Dernier message: 03/12/2009, 10h42
  2. Ecrire du texte sur une fenêtre de Jeu vidéo (OSD)
    Par zenway dans le forum DirectX
    Réponses: 7
    Dernier message: 07/03/2009, 15h06
  3. [GLFW]Ecrire du texte sur une fenêtre GLFW
    Par iluv dans le forum OpenGL
    Réponses: 14
    Dernier message: 12/04/2006, 17h00
  4. Ecrire du texte sur une Overlay Surface
    Par deakuk dans le forum DirectX
    Réponses: 1
    Dernier message: 17/02/2006, 14h52
  5. [VMR9][D3D9]ecrire un texte sur une surface
    Par drizztfr dans le forum DirectX
    Réponses: 2
    Dernier message: 13/11/2003, 16h06

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