2008-12-11 28 views
6

¿Cómo puedo escribir un texto semi transparente sobre una imagen (JPG, BMP), o un texto transparente (color como iguales Fondo de la imagen), pero con una sombra, algo que desee hacer a la marca de agua de las imágenes .Escribir texto transparente en la imagen

que quiero lograr que el uso de Win32 Delphi.

Respuesta

3

supongo que lo que estamos tratando de lograr es un poco más complicado que simplemente escribir texto con un fondo transparente.; es decir, está tratando de obtener algún tipo de texto alfa-mezclado escrito en la imagen.
El método más simple sería hacer uso de las rutinas GDI +. Están encapsulados para delphi y están disponibles para su descarga desde http://www.progdigy.com/. Hay muchos ejemplos allí que deberían ser utilizables como ejemplo.

+0

Progdigy.com está caído? No puedo acceder a eso – Ampere

+0

Parece que hubo algún desacuerdo entre el desarrollador de 'GDI plus' para Delphi y Embarcadero, no sé si se ha retirado en respuesta a esto. Podría intentar buscar algunas alternativas como [GDI plus] de Erik Van Bilsen (http://www.bilsen.com/gdiplus/index.shtml). – Petesh

2

No lo he probado, pero le dará una idea de a dónde ir. la clave es el estilo de pincel

algo como esto:

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

X-Ray, eso es escribirán el texto con color negro, quiero que el texto sea semi transparente nt o transparente con sombra de color –

+0

fuente se utiliza, no el color del lápiz –

+0

> se utiliza el color de fuente, color de la pluma no gracias por la corrección, Jim. –

3

La sombra es fácil:

// 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'); 

Este es un texto con un fondo transparente. ¿O quisieras que el texto en sí mismo sea igual de transparente? Eso es un poco más complicado. Tendría que dibujarlo manualmente. Una forma fácil de hacerlo sería tomar muestras del promedio del color del área que está escribiendo en la imagen. Luego configure el color de su fuente para que sea un poco más claro y su sombra sea un poco más oscura. Entonces que tipo de mezcla en

+0

Jim, quería texto transparente con la sombra, o texto semi transparente fondo no transparente –

+0

Sí, no estaba seguro. La mezcla alfa es un poco más complicada. –

+0

Buen código, simple pero cumple su función. +1 –

1

podría utilizar el bitblt rutinas para combinar una imagen para hacer un lienzo común, a continuación, guardar la imagen de nuevo.

+1

skamradt, ¿Algún código de muestra? –

6

Una opción es utilizar la función AlphaBlend en la unidad windows.pas. Algo como esto producirá texto semitransparente (con una gota de sombra - edificio de la respuesta de Jim McKeeth) sobrepuesto en una imagen:


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

Esta función se basa en la idea de Dave Elsberry.

Qué es diferente:

  • Sorteos sólo la sombra transparente
  • Utiliza casi 2 veces menos RAM
  • Parámetros

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; 
Cuestiones relacionadas