1

ソース画像の透明度を維持しながら、通常の (TBitmap) 画像に完全に透明なピクセルと部分的に透明なピクセルを含むソース画像 (GR32 TBitmap32) を描画しようとしています。

私はこれを使用します:

BMP32.DrawTo(BMP.Canvas.Handle, 0, 0);

ただし、画像は透過的に描画されません。


コード:
すべてが非常に基本的です: アプリケーションの起動時にイメージをロードする背景ビットマップ (Bkg) があります。次に、手順 Apply で、ディスクから 2 番目の画像 (透明度のある画像) を読み込み、背景の上に描画します。

var Bkg: TBitmap;

procedure TfrmPhoto.FormCreate(Sender: TObject);
begin
 Bkg:= LoadGraphEx(GetAppDir+ 'bkg.bmp'); { Load bitmap from file }
 {
 Bkg.Transparent:= TRUE;
 Bkg.PixelFormat:= pf32bit;
 Bkg.TransparentColor:= clPink;
 }
end;


procedure TfrmPhoto.Apply2;
VAR
   Loader: TBitmap;
   BMP32: tbitmap32;
begin
 BMP32:= TBitmap32.Create;
 TRY

  Loader:= TBitmap.Create;
  TRY
   Loader.LoadFromFile('c:\Transparent.BMP');
   BMP32.Assign(Loader);
  FINALLY
   FreeAndNil(Loader);
  END;

  { Mix images }
  BMP32.DrawTo(Bkg.Canvas.Handle, 0, 0);    <----- The problem is here

  imgPreview.Picture.Assign(Bkg);    { This is a TImage where I see the result }
 FINALLY
  FreeAndNil(BMP32);
 END;
end;
4

3 に答える 3

4

すでに提案されているように、TBitmap32 ドメインで完全にブレンド操作を実行することをお勧めします! この理由は、ブレンディングに関してより多くの選択肢を提供し、利用可能な場合は MMX/SSE/SSE2 を使用するためです (最新のマシンでは常にそうです)。これを使用すると、通常、GDI にブレンディングを実行させる場合とは対照的に、顕著なパフォーマンスの向上を得ることができます。

特に、GDI は通常 SIMD オペコード (MMX/SSE) を使用しないため、これは良い考えではありません。

また、各パーツがどの程度変化するかにもよります。たとえば、通常、背景はかなり静的であり、TBitmpa32 に転送する必要があるのは、たまに変更があった場合 (VCL スタイルや UI テーマの変更など) だけです。各転送 (GR32 <-> TBitmap など) で、暗黙的な変換 (DIB <-> DDB) が発生する可能性があり、これにより、ブレンド全体が O(n²) 操作になります。そのため、TBitmap32 に (暗黙的な変換を使用して) 1 回だけ転送してから、完全に GR32 ドメインでブレンドを実行することをお勧めします。

反対に、TBitmap32 がかなり静的で、TBitmap (または背景) が大きく変化する場合は、GR32 をそのままにして、TBitmap32 を TBitmap にコピーし、GDI とのブレンドを実行する方がよいかもしれません。GDI ブレンディングがわずかに遅いという事実にもかかわらず、追加のコピーを回避します。そうしないと、処理速度が限界に達することはありませんが、メモリ スループットがボトルネックになる可能性があります。

于 2014-01-31T08:28:36.397 に答える