在Firemonkey上,如何在画布上绘制蒙版位图?

4 delphi firemonkey

我有一个位图和一个蒙版(还有一个位图)。我想在蒙版上绘制位图(如下图所示)

在蒙版上绘制位图

如何在 Delphi 上使用Firemonkey执行此操作?

Tom*_*erg 6

使用TBitmap.CreateFromBitmapAndMask()

constructor CreateFromBitmapAndMask(const Bitmap, Mask: TBitmap);
Run Code Online (Sandbox Code Playgroud)

文档说:

创建的 TBitmap 中每个颜色像素的 Alpha 通道值等于 Mask 中的红色通道值。

并进一步:

提示:为了获得更好的结果,请使用灰度图像作为蒙版。它具有等量的绿色、红色和蓝色。

提示:蒙版和基础位图必须具有相同的尺寸。否则,新的 TBitmap 的尺寸将等于 0。

在一个简单的测试中,例如:

procedure TForm19.Button1Click(Sender: TObject);
var
  bmp, msk: TBitmap;
begin
  bmp := nil;
  msk := nil;
  try
    bmp := TBitmap.Create;
    msk := TBitmap.Create;
    bmp.LoadFromFile('C:\tmp\Imgs\4.bmp');
    msk.LoadFromFile('C:\tmp\Imgs\TestImage04.bmp');
    Image1.Bitmap := bmp;
    Image2.Bitmap := msk;
    Image3.Bitmap.CreateFromBitmapAndMask(bmp, msk);
  finally
    bmp.Free;
    msk.Free;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

结果如下:

在此输入图像描述

编辑

为了使 的结果CreateFromBitmapAndMask(bmp, msk);透明地绘制在表单上,​​必须premultiplied先将其赋值给Image3。我们需要以下程序,

procedure PremultiplyBitmapAlpha(bmp:TBitmap);
var
  X, Y: Integer;
  M: TBitmapData;
  C: PAlphaColorRec;
begin
  if bmp.Map(TMapAccess.ReadWrite, M) then
  try
    for Y := 0 to bmp.Height - 1 do
      for X := 0 to bmp.Width - 1 do
      begin
        C := @PAlphaColorArray(M.Data)[Y * (M.Pitch div 4) + X];
        C^.Color := PremultiplyAlpha(C^.Color);
      end;
  finally
    bmp.Unmap(M);
  end;
end;
Run Code Online (Sandbox Code Playgroud)

和另一个res用于此目的的临时位图。测试代码现在如下所示:

procedure TForm14.Button1Click(Sender: TObject);
var
  bmp, msk, res: TBitmap;
begin
  bmp := nil;
  msk := nil;
  res := nil;
  try
    bmp := TBitmap.Create;
    msk := TBitmap.Create;
    bmp.LoadFromFile('C:\tmp\Imgs\4.bmp');
    msk.LoadFromFile('C:\tmp\Imgs\TestImage04.bmp');

    Image1.Bitmap := bmp;
    Image2.Bitmap := msk;

    res := TBitmap.Create;
    res.CreateFromBitmapAndMask(bmp, msk);

    PremultiplyBitmapAlpha(res);
    Image3.Bitmap := res;
  finally
    bmp.Free;
    msk.Free;
    res.Free;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

和图像(带有修改后的背景颜色以便更好地演示):

在此输入图像描述