2008-12-11 11 views
6

Comment puis-je écrire un texte semi-transparent sur une image (Jpg, Bmp), ou un texte transparent (couleur comme même image de fond) mais avec une ombre, quelque chose que je veux faire pour filigraner les images .Écriture de texte transparent sur l'image

Je veux accomplir cela en utilisant Delphi win32.

Répondre

3

Je suppose que ce que vous essayez d'accomplir est un peu plus compliqué que d'écrire simplement du texte avec un fond transparent; c'est-à-dire que vous essayez d'obtenir une forme de texte alpha-mélangé écrit sur l'image.
La méthode la plus simple serait d'utiliser les routines GDI +. Ils sont encapsulés pour delphi et disponibles au téléchargement à partir de http://www.progdigy.com/. Il existe de nombreux exemples qui devraient être utilisables à titre d'exemple.

+0

Progdigy.com est en panne? Je ne peux pas y accéder. – Ampere

+0

Il semble qu'il y ait eu quelques désaccords entre le développeur de 'GDI plus' pour Delphi et Embarcadero, je ne sais pas si cela a été tiré en réponse à cela. Vous pourriez essayer de chercher des alternatives telles que [GDI plus] d'Erik Van Bilsen (http://www.bilsen.com/gdiplus/index.shtml). – Petesh

2

Je ne l'ai pas testé mais ça vous donnera une idée de l'endroit où aller. la clé est le style de la brosse.

quelque chose comme ceci:

img.Canvas.Brush.Style:=bsClear; 
img.Canvas.Font.Color:=clBlack; 
img.Canvas.TextOut(0, 0, 'hi there'); 
+0

X-Ray, c'est écriront le texte avec la couleur noire, je veux que le texte soit semi transpare nt ou transparent avec ombre –

+0

La couleur de la police est utilisée, pas la couleur du crayon –

+0

> La couleur de la police est utilisée, pas la couleur du crayon Merci pour la correction, jim. –

3

L'ombre est facile:

// Bold shows up better when over an image 
image1.Canvas.Font.Style := [fsBold]; 
// Write the shadow first 
image1.Canvas.Brush.Style:=bsClear; 
image1.Canvas.Font.Color := clGrayText; 
image1.Canvas.TextOut(1, 1, 'hi there'); 
// Then put the text on top (slightly offset) 
image1.Canvas.Brush.Style:=bsClear; 
image1.Canvas.Font.Color :=clBlack; 
image1.Canvas.TextOut(0, 0, 'hi there'); 

Ceci est un texte avec un fond transparent. Ou vouliez-vous que le texte lui-même soit simi-transparent? C'est un peu plus compliqué. Vous auriez besoin de le dessiner manuellement. Un moyen facile de le faire serait d'échantillonner la moyenne de la couleur de la zone que vous écrivez sur l'image. Réglez ensuite la couleur de votre police pour qu'elle soit un peu plus claire et que votre ombre soit un peu plus foncée. Ensuite, il se fond dans.

+0

Jim, je voulais un texte transparent avec ombre, ou un texte semi-transparent pas transparent fond –

+0

Ouais je n'étais pas sûr. Le mélange alpha est un peu plus compliqué. –

+0

Bon code, simple mais fait le boulot. +1 –

1

Vous pouvez utiliser les routines bitblt pour fusionner une image en un canevas commun, puis enregistrer à nouveau l'image.

+1

skamradt, Any sample code? –

6

Une option consiste à utiliser la fonction AlphaBlend dans l'unité Windows.pas. Quelque chose comme ceci produira texte semi-transparent (avec une ombre - bâtiment sur la réponse de Jim McKeeth) overlayed sur une image:


uses Windows, Graphics; 
. 
. 
. 
var 
    BackgroundImage: Graphics.TBitmap; { need to call out specifically for Graphics.TBitmap 
             because the Windows unit also has a TBitmap 
             declaration } 
    TextImage: Graphics.TBitmap; 
    BlendFunc: BLENDFUNCTION; 
begin 
    BlendFunc.BlendOp := AC_SRC_OVER; 
    BlendFunc.BlendFlags := 0; 
    BlendFunc.SourceConstantAlpha := $C0; { a hex value from $00-$FF (0-255). 
              Represents the percent of opaqueness: 
              $00 is completely transparent, 
              $FF is completely opaque. 
              $C0 is 75% opaque } 
    BlendFunc.AlphaFormat := AC_SRC_ALPHA; 

    { BackgroundImage is for holding the image you want to overlay text onto } 
    BackgroundImage := Graphics.TBitmap.Create; 
    try 
     BackgroundImage.LoadFromFile('yourimagehere.bmp'); 

     { Create another TBitmap to hold the text you want to overlay } 
     TextImage := Graphics.TBitmap.Create; 
     try 
     { Set this bitmap to have the same dimensions as the 
      background image you want the text to appear on. } 
     TextImage.Height := BackgroundImage.Height; 
     TextImage.Width := BackgroundImage.Width; 

     { In my limited experience with AlphaBlend, Black is always 100% 
      transparent. So, paint TextImage completely Black. Play around 
      with this to see the effect it has on the final outcome. } 
     TextImage.Canvas.Brush.Color := clBlack; 
     TextImage.Canvas.FloodFill(0, 0, clNone, fsBorder); 

     TextImage.Canvas.Font.Style := [fsBold]; 

     { Write the shadow first } 
     TextImage.Canvas.Brush.Style := bsClear; 
     TextImage.Canvas.Font.Color := clDkGray; 
     TextImage.Canvas.TextOut(11, 11, 'Test'); 

     { Then put the text on top (slightly offset) } 
     TextImage.Canvas.Brush.Style := bsClear; 
     TextImage.Canvas.Font.Color := clMaroon; 
     TextImage.Canvas.TextOut(10, 10, 'Test'); 

     { Use the AlphaBlend function to overlay the bitmap holding the text 
      on top of the bitmap holding the original image. } 
     Windows.AlphaBlend(BackgroundImage.Canvas.Handle, 0, 0, 
          TextImage.Width, TextImage.Height, 
          TextImage.Canvas.Handle, 0, 0, TextImage.Width, 
          TextImage.Height, BlendFunc); 

     { Assign the now updated BackgroundImage to a TImage control for display } 
     Image1.Picture.Bitmap.Assign(BackgroundImage); 
     finally 
     TextImage.Free; 
     end; 
    finally 
     BackgroundImage.Free; 
    end; 
    end; 
2

Cette fonction est basée sur l'idée de Dave Elsberry.

Ce qui est différent:

  • Tirages au sort que l'ombre transparente
  • Il utilise presque 2 fois moins de RAM
  • Paramètres

procedure DrawShadowText(aCanvas: TCanvas; CONST Text: string; CONST X, Y, Opacity: Integer; TextColor, ShadowColor: TColor);  
{ Opacity a value from 0-255: 
    $00 is completely transparent, 
    $FF is completely opaque. 
    $C0 is 75% opaque } 
CONST ShadowSize= 1; 
VAR 
    TempBMP: TBitmap; 
    BlendFunc: BLENDFUNCTION; 
    H, W: Integer; 
begin 
BlendFunc.BlendOp := AC_SRC_OVER; 
BlendFunc.BlendFlags := 0; 
BlendFunc.SourceConstantAlpha := Opacity; 
BlendFunc.AlphaFormat := AC_SRC_ALPHA; 

{ Create another TBitmap to hold the text you want to overlay } 
TempBMP := Graphics.TBitmap.Create; 
TRY 
    TempBMP.Canvas.Font.Style := [fsBold]; 
    TempBMP.Canvas.Brush.Style := bsClear; 

    W:= TempBMP.Canvas.TextWidth(Text); 
    H:= TempBMP.Canvas.TextHeight(Text); 

    TempBMP.SetSize(W+ShadowSize, H+ShadowSize); 

    { In AlphaBlend, Black is always 100% transparent. So, paint TempBMP completely Black. } 
    TempBMP.Canvas.Brush.Color := clBlack; 
    TempBMP.Canvas.FloodFill(0, 0, clNone, fsBorder); 

    { Write the shadow first } 
    TempBMP.Canvas.Font.Color := ShadowColor; 
    TempBMP.Canvas.TextOut(ShadowSize, ShadowSize, Text);  { Diagonal left shadow } 
    TempBMP.Canvas.TextOut(ShadowSize, 0,   Text);  { Left shadow } 

    { Draw the text with transparency: 
    TempBMP.Canvas.Brush.Style := bsClear; 
    TempBMP.Canvas.Font.Color := TextColor; 
    TempBMP.Canvas.TextOut(0, 0, Text); } 

    { Use the AlphaBlend function to overlay the bitmap holding the text on top of the bitmap holding the original image. } 
    Windows.AlphaBlend(aCanvas.Handle, 
         x, y, TempBMP.Width, TempBMP.Height, 
         TempBMP.Canvas.Handle, 0, 0, TempBMP.Width, TempBMP.Height, 
         BlendFunc); 

    { Draw the text at 100% opacity } 
    aCanvas.Font.Style := [fsBold]; 
    aCanvas.Brush.Style := bsClear; 
    aCanvas.Font.Color := TextColor; 
    aCanvas.TextOut(x, y-1, Text); 
FINALLY 
    FreeAndNil(TempBMP); 
END; 
end; 



procedure TfrmTest.UseIt; 
VAR BackgroundImage: tbitmap; 
begin 
BackgroundImage := Graphics.TBitmap.Create; 
try 
    BackgroundImage.LoadFromFile('c:\test.bmp'); 
    DrawShadowText (BackgroundImage.Canvas, 'This is some demo text', 20, 40, 140, clRed, clSilver); 
    Image1.Picture.Bitmap.Assign(BackgroundImage); 
FINALLY 
    BackgroundImage.Free; 
end; 
end;