Написание прозрачного текста на изображении

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

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

11.12.2008 19:00:17
6 ОТВЕТОВ
РЕШЕНИЕ

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

3
11.12.2008 21:03:18
Progdigy.com не работает? Я не могу получить к нему доступ.
Migrate2Lazarus see my profile 6.04.2014 09:39:51
Похоже, что между разработчиком GDI plusDelphi и Embarcadero возникли разногласия , я не знаю, было ли это сделано в ответ на это. Вы можете попробовать поискать некоторые альтернативы, такие как GDI plus Эрика Ван Билсена .
Petesh 6.04.2014 10:52:15

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

что-то вроде этого:

img.Canvas.Brush.Style:=bsClear;
img.Canvas.Font.Color:=clBlack;
img.Canvas.TextOut(0, 0, 'hi there');
2
23.12.2008 22:29:14
Рентген, это напишет текст черным цветом, я хочу, чтобы текст был полупрозрачным или прозрачным с тенью
Mohammed Nasman 11.12.2008 19:07:28
Используется цвет шрифта, а не цвета пера
Jim McKeeth 11.12.2008 20:52:28
> Используется цвет шрифта, а не цвет пера, спасибо за исправление, Джим.
X-Ray 23.12.2008 22:29:45
Установка кисти в bsClear на самом деле не рисует ее прозрачной, она использует цвет кисти в качестве цвета фона. bsClear отлично работает, если у вас есть однотонный фон, но не работает, если у вас его нет. Если вы хотите иметь фактический прозрачный фон для текста, вы должны использовать: SetBkMode (Canvas.Handle, TRANSPARENT); И обязательно вызовите SetBkMode после того, как вы установили Canvas.Brush.Color.
Ben C 7.08.2013 23:08:19

Тень проста:

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

Это текст с прозрачным фоном. Или вы хотели, чтобы сам текст был прозрачным? Это немного сложнее. Вам нужно будет нарисовать его вручную. Вместо этого проще всего сделать выборку среднего значения цвета области, которую вы пишете на изображении. Затем установите цвет шрифта немного светлее, а тень - темнее. Тогда это как бы сливается.

3
11.12.2008 20:54:46
Джим, я хотел прозрачный текст с тенью или полупрозрачный текст с непрозрачным фоном
Mohammed Nasman 12.12.2008 08:52:13

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

1
11.12.2008 23:17:53

Одним из вариантов является использование функции 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;
6
12.12.2008 15:48:17

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

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

  • Рисует только тень прозрачно
  • Он использует почти в 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
10.04.2014 11:44:42