9

アルファ透過の長方形とアルファ透過の画像を使用して、非常に複雑な画像を描画したいと考えています。 Mitovの GDI+ ラッパーがありますが、32 ビットの BMP ファイルをサポートしていないようです。BMP は PNG よりもはるかに高速なので、使用したいと考えています。 GDI+ の SynGDI ラッパーがありますが、非常に基本的なようで、ドキュメントはありません。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+ の方が高速である必要があると思いますが、そうですか?

問題は、アルファ透明な長方形とビットマップを簡単に (大量のコードなしで) 描画する方法です。

Delphi の優先: 7. 私は 2005 と XE3 も持っていますが、7 はスピードの悪魔なので、7 以降で動作するものを最も望んでいます。

4

1 に答える 1

13

通常の TBitmap を用意すれば、bmp.Canvas.Handle を割り当てるだけで、どの GDI+ 実装も使用できます。コンパイルの問題は、フォルダー内の古い 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;

デモ

于 2013-03-15T07:05:48.727 に答える