使用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)
和图像(带有修改后的背景颜色以便更好地演示):