// ATransparency <= 0 ---> fully opaque
// ATransparency >= 1 --> fully transparent
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;