在图像上写透明文本

时间:2008-12-11 19:00:17

标签: delphi image-processing

如何在图像(Jpg,Bmp)或透明文本(颜色与背景图像相同)上书写半透明文本,但带阴影,我想用水印图像。

我想用Delphi win32来实现这个目标。

6 个答案:

答案 0 :(得分:6)

一种选择是在Windows.pas单元中使用AlphaBlend函数。像这样的东西会产生半透明的文字(带有投影 - 建立在Jim McKeeth的回应上)覆盖在图像上:

  
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;

答案 1 :(得分:3)

阴影很容易:

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

这是具有透明背景的文字。或者您是否希望文本本身是透明的?这有点棘手。您需要手动绘制它。一种简单的方法是采样您在图像上书写的区域的平均颜色。然后将字体颜色设置得稍微亮一点,让阴影变暗一点。然后它融入了。

答案 2 :(得分:3)

我认为你想要完成的事情比简单地用透明背景写文字要复杂一些;即你试图在图像上写下某种形式的阿尔法混合文本 最简单的方法是使用GDI +例程。它们封装为delphi,可从http://www.progdigy.com/下载。有很多例子可以作为例子使用。

答案 3 :(得分:2)

我没有测试过,但它会让你知道该去哪里。关键是画笔风格。

类似的东西:

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

答案 4 :(得分:2)

此功能基于Dave Elsberry的想法。

有什么不同:

  • 透明地仅绘制阴影
  • 它使用的RAM少了近2倍
  • 参数

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;

答案 5 :(得分:1)

您可以使用bitblt例程将图像合并到公共画布,然后再次保存图像。

豫ICP备18024241号-1