我想用alpha透明矩形和alpha透明图像绘制非常复杂的图像。 There is GDI+ wrapper from Mitov,但它似乎不支持32位BMP文件加上它重新调整它们并且文档很糟糕。 BMP比PNG更快,所以我想使用它们。 There is SynGDI wrapper of GDI+,但它似乎非常基本,没有相关文档。 GDI还有这个技巧:
procedure DrawAlphaAPI(Source: TBitmap; Destination: TCanvas;
const X, Y: Integer; const Opacity: Byte = 255);
var BlendFunc: TBlendFunction;
begin
BlendFunc.BlendOp := AC_SRC_OVER;
BlendFunc.BlendFlags := 0;
BlendFunc.SourceConstantAlpha := Opacity;
if Source.PixelFormat = pf32bit then
BlendFunc.AlphaFormat := AC_SRC_ALPHA
else
BlendFunc.AlphaFormat := 0;
Windows.AlphaBlend(Destination.Handle, X, Y, Source.Width, Source.Height,
Source.Canvas.Handle, 0, 0, Source.Width, Source.Height, BlendFunc);
end;
但是当我用Opacity = 255调用它时,它不能正确地绘制32位位图(就像它们应该是完全的那样它们是半透明的)。 我不想使用Scanline来使像素透明,因为这太复杂了,无法以这种方式绘制所有透明矩形。 另外,我在现代计算机上的GDI +应该更快,我是对的吗?
所以问题是:如何轻松绘制alpha透明矩形和位图(没有大量代码)?
首选德尔福:7。我也有2005和XE3,但由于7是速度恶魔,我最希望从7开始工作。
答案 0 :(得分:10)
如果准备普通的TBitmap,可以使用任何GDI +实现只分配bmp.Canvas.Handle。 您编译时的问题可能是由文件夹中的旧DirctDraw-Version引起的,只需将其删除即可。
implementation
uses GDIPAPI, GDIPOBJ;
{$R *.dfm}
Procedure PrepareBMP(bmp: TBitmap; Width, Height: Integer);
var
p: Pointer;
begin
bmp.PixelFormat := pf32Bit;
bmp.Width := Width;
bmp.Height := Height;
bmp.HandleType := bmDIB;
bmp.ignorepalette := true;
bmp.alphaformat := afPremultiplied;
// clear all Scanlines
p := bmp.ScanLine[Height - 1];
ZeroMemory(p, Width * Height * 4);
end;
procedure TForm2.Button1Click(Sender: TObject);
var
bmp: TBitmap;
G: TGPGRaphics;
B: TGPSolidBrush;
begin
bmp := TBitmap.Create;
try
PrepareBMP(bmp, 300, 300);
G := TGPGRaphics.Create(bmp.Canvas.Handle);
B := TGPSolidBrush.Create(MakeColor(100, 255, 0, 0));
try
G.SetSmoothingMode(SmoothingModeHighQuality);
G.FillEllipse(B, MakeRect(0.0, 0, 300, 300));
B.SetColor(MakeColor(100, 0, 255, 128));
G.FillEllipse(B, MakeRect(40.0, 40, 260, 260));
finally
B.Free;
G.Free;
end;
// draw overlapping in Form Canvas to display transparency
Canvas.Draw(0, 0, bmp);
Canvas.Draw(100, 100, bmp);
finally
bmp.Free;
end;
end;