Написание прозрачного текста на изображении - PullRequest
6 голосов
/ 11 декабря 2008

Как я могу написать полупрозрачный текст на изображении (Jpg, Bmp) или прозрачный текст (цвет как на том же фоновом изображении), но с тенью, что я хочу сделать, чтобы сделать водяные знаки на изображениях.

Я хочу добиться этого, используя Delphi win32.

Ответы [ 6 ]

6 голосов
/ 12 декабря 2008

Один из вариантов - использовать функцию AlphaBlend в модуле Windows.pas. Примерно так получится полупрозрачный текст (с тенью), основанный на ответе Джима Маккита, наложенный на изображение:

  
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;
3 голосов
/ 12 декабря 2008

Полагаю, то, что вы пытаетесь выполнить, немного сложнее, чем просто написание текста с прозрачным фоном; то есть вы пытаетесь получить некоторую форму альфа-смешанного текста, написанного на изображении.
Самый простой способ - использовать подпрограммы GDI +. Они инкапсулированы для delphi и доступны для скачивания по адресу http://www.progdigy.com/.. Существует множество примеров, которые следует использовать в качестве примера.

3 голосов
/ 11 декабря 2008

Тень легка:

// 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 голосов
/ 06 апреля 2014

Эта функция основана на идее Дэйва Элсберри.

Что отличается:

  • Прозрачно рисует только тень
  • Он использует почти в 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;
2 голосов
/ 11 декабря 2008

Я не проверял, но это даст вам представление, куда идти. ключ стиль кисти.

как то так:

img.Canvas.Brush.Style:=bsClear;
img.Canvas.Font.Color:=clBlack;
img.Canvas.TextOut(0, 0, 'hi there');
1 голос
/ 12 декабря 2008

Вы можете использовать процедуры bitblt , чтобы объединить изображение в общий холст, а затем снова сохранить изображение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...