【问题标题】:How to draw transparent with alpha transparency in Delphi?如何在 Delphi 中用 alpha 透明度绘制透明?
【发布时间】:2013-03-14 23:40:03
【问题描述】:

我想用 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 透明矩形和位图(无需大量代码)?

首选 Delphi:7。我也有 2005 和 XE3,但由于 7 是速度恶魔,我最希望从 7 开始工作。

【问题讨论】:

  • 如果你可以使用支持Delphi 2009 up的this wrapper,你可能会写code like this,看起来很复杂,但是你需要知道你可以用那个颜色矩阵修改color adjustment和我正在加载一个要在该代码中混合 alpha 的文件(例如,您可以从传递的 TBitmap 对象创建一个 GPBitmap)。
  • @TLama 谢谢,这个 GDI+ 似乎是迄今为止最好的。其他都很烂。 Progdigy 的一个无法编译(7、2005 和 XE3),Mitov 的一个在绘制后破坏图像,Synopse 的一个不完整。
  • FWIW:我发现these articles 很有趣。
  • @UliGerhardt 确实很有趣。谢谢!

标签: image delphi graphics gdi+


【解决方案1】:

如果您准备普通的 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;

【讨论】:

  • 谢谢你,笨蛋!我不知道 bmp.AlphaFormat,因为在我购买 XE3 之前,我曾在较旧的 Delphis 上工作并且没有=这样的东西。但是现在,当我做 bmp.AlphaFormat :=afDefined;我通常只是加载 32 位位图和 Canvas.Draw() 他们!
  • 我还删除了 DirectDraw.pas 并且 Progdidy 的 GDI 编译得很好(至少在 XE3 中),谢谢!
猜你喜欢
  • 2012-12-19
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
  • 2017-12-13
  • 1970-01-01
  • 1970-01-01
  • 2010-11-16
  • 2010-12-09
相关资源
最近更新 更多