Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Рисование текста с полупрозрачностью на TFPImageCanvas без использования сторонних библиотек.

Delphi , Графика и Игры , Canvas

 

В предыдущих обсуждениях проблемы с отрисовкой psInsideframe на TFPImageCanvas, мы столкнулись с еще одной задачей: как рисовать полупрозрачный текст, не прибегая к использованию сторонних библиотек, таких как FreeType. Использование FTFont/TFreeTypeFont добавляет значительный объем зависимостей (около 30МБ), что нежелательно для портативных приложений, особенно для встраиваемых устройств с ограниченными ресурсами.

Ранее мы обсуждали проблему с отрисовкой psInsideframe и выяснили, что эта функциональность не реализована в fcl-image. Также мы нашли способ копирования участков изображения между TFPImageCanvas и TPortableNetworkGraphic с использованием CopyRect. Теперь, благодаря помощи @wp, у нас есть решение для отрисовки полупрозрачного текста, которое не требует дополнительных библиотек.

Решение, предложенное @wp, заключается в использовании вспомогательной bitmap для отрисовки текста и последующем смешивании (blending) этой bitmap с основным изображением. Этот подход позволяет добиться полупрозрачности текста, не прибегая к использованию FreeType или других сторонних библиотек.

Альтернативное решение:

Хотя предложенное решение является отличным способом достижения полупрозрачности, оно имеет некоторые недостатки, связанные с созданием и копированием bitmap. Альтернативным (хотя и менее эффективным) решением может быть использование TCanvas.Brush.Style и TCanvas.Brush.Color для создания эффекта полупрозрачности за счет изменения альфа-канала цвета кисти. Однако, этот способ не всегда дает желаемый результат, особенно при работе с текстом, и может привести к непредсказуемым артефактам.

Пример кода (реализация решения @wp):

unit Unit1;

interface
uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls,
  FPImage, FPCanvas, FPImgCanv;

type
  { TForm1 }
  TForm1 = class(TForm)
    Image1: TImage;
    procedure FormCreate(Sender: TObject);
  private
  public
  end;

var
  Form1: TForm1;
  FImage: TBitmap;

procedure DrawText(AImage: TFPCustomImage; X, Y: Integer; AText: String;
  AFont: TFont; ATransparency: Single);
  // Calculate the alpha value from the "brightness" of the given pixel
  // (average of RGB). Multiply by the transparency factor to get a semitransparent
  // mask.
  function CalcAlpha(AColor: TFPColor): Word;
  begin
    Result := trunc((1.0*AColor.Red + AColor.Green + AColor.Blue) / 3 * (1.0 - ATransparency));
  end;
var
  bmp: TBitmap;
  mask: TLazIntfImage;
  ext: TSize;
  ix, iy: Integer;
  fntColor: TFPColor;
  maskColor: TFPColor;
  imgColor: TFPColor;
begin
  // Create aux bitmap for white text on black background as alpha mask
  bmp := TBitmap.Create;
  try
    bmp.Pixelformat := pf32Bit;
    // Measure the size of the text and set the size of the aux bitmap accordingly
    bmp.Canvas.Font.Assign(AFont);
    ext := bmp.Canvas.TextExtent(AText);
    bmp.SetSize(ext.CX, ext.CY);
    // We need a black background of the aux bitmap
    bmp.Canvas.Brush.Color := clBlack;
    bmp.Canvas.FillRect(0, 0, bmp.Width, bmp.Height);
    // Draw white text on black background of aux bitmap
    bmp.Canvas.Font.Color := clWhite;
    bmp.Canvas.Brush.Style := bsClear;
    bmp.Canvas.TextOut(0, 0, AText);
    // Use LazIntfImage to convert the gray scales of the aux bitmap to alpha
    // value. The non-zero pixels in the mask are replaced by the original font
    // color. Finally the mask pixels are alpha-blended with the image pixels.
    fntColor := TColorToFPColor(AFont.Color);
    mask := bmp.CreateIntfImage;
    try
      for iy := 0 to mask.Height-1 do
      begin
        for ix := 0 to mask.Width-1 do
        begin
          maskColor := mask.Colors[ix, iy];
          if (maskColor = colBlack) then   // The mask is fully transparent here
            maskColor.Alpha := alphaTransparent
          else begin
            // Non fully-transparent pixels get the calculated alpha value...
            maskColor.Alpha := CalcAlpha(maskColor);
            // ... and the color of the font.
            maskColor.Red := fntColor.Red;
            maskColor.Green := fntColor.Green;
            maskColor.Blue := fntColor.Blue;
          end;
          // Alpha-blend the mask pixel with the image pixel
          imgColor := AImage.Colors[X + ix, Y + iy];
          AImage.Colors[X + ix, Y + iy] := AlphaBlend(imgColor, maskColor);
        end;
      end;
    finally
      mask.Free;
    end;
  finally
    bmp.Free;
  end;
end;

implementation
{$R *.lfm}

{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
begin
  FImage := TBitmap.Create;
  FImage.SetSize(800, 400);
  FImage.Canvas.GradientFill(Rect(0,0,Width,Height),clAqua,clFuchsia,gdHorizontal);
  TImage1.Picture.Bitmap.Assign(FImage);

  // Пример использования DrawText
  DrawText(FImage, 20, 40, 'HELLO!', FImage.Canvas.Font, 0.5); // Полупрозрачный текст
end;

end.

Пояснения к коду:

  • DrawText - процедура для отрисовки полупрозрачного текста.
  • CalcAlpha - функция для расчета альфа-канала на основе яркости пикселя.
  • Создается вспомогательная bitmap (bmp) черного цвета.
  • На этой bitmap рисуется текст белым цветом.
  • TLazIntfImage используется для преобразования оттенков серого bitmap в альфа-канал.
  • Пиксели маски смешиваются с пикселями основного изображения, создавая эффект полупрозрачности.

Вывод:

Решение, предложенное @wp, позволяет рисовать полупрозрачный текст на TFPImageCanvas без использования сторонних библиотек. Хотя оно и требует создания и копирования bitmap, это компромисс, позволяющий избежать дополнительных зависимостей и сохранить портативность приложения. В будущем, возможно, будут разработаны более эффективные способы решения этой задачи, но на данный момент это является оптимальным вариантом. Благодаря этому решению, мы можем создавать более сложные и визуально привлекательные приложения, сохраняя при этом их легковесность и переносимость.

Создано по материалам из источника по ссылке.

Решение для отрисовки полупрозрачного текста на TFPImageCanvas без использования сторонних библиотек через создание вспомогательной bitmap и её последующего смешивания с основным изображением.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Canvas ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-06-15 23:41:19/0.0060639381408691/1