この質問は、私のearlier questionと関連しています。AlphablendとTransparentBlt
ソースレイヤの特定の部分にのみアルファを適用して2つのレイヤを結合したいとします。私が試した1つの方法は、SourceConstantAlphaを$ ffに設定することでした(関数にソースレイヤーのアルファチャンネルを使用させる)。
この種の作品 - 遅いですが(私はScanLinesを使ってスピードを上げることができますが)、アルファチャンネルを何に設定するか分かりません。ドキュメントは計算があることを示唆している:
st.Red = Src.Red + (1 - Src.Alpha) * Dst.Red
私は推測作業により、いくつかの異なる値を試してみましたが、私の最初の質問は:どのように私は、アルファ値を計算していますか?
他のいくつかの質問を読んだ後、私は透明ではなく、マスキング(高速)であるTransparentBlt関数を見つけました。 これらの2つの呼び出しを組み合わせる方法があります)?
unit MainWnd;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, ControlsEx;
type
{------------------------------------------------------------------------------}
TfrmMain = class(TForm)
PaintBox1: TPaintBox;
procedure PaintBox1Paint(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
frmMain: TfrmMain;
implementation
{$R *.dfm}
{..............................................................................}
procedure copyToAlpha(const in_bitmap : TBitmap; const in_transparentColor : TColor;
const in_transparency : integer);
var
x : integer;
y : integer;
p : integer;
begin
ASSERT(in_bitmap.PixelFormat = pf32bit);
for x := 0 to in_bitmap.Width - 1 do
begin
for y := 0 to in_bitmap.Height - 1 do
begin
p := in_bitmap.Canvas.Pixels[x, y];
if TColor(p) <> in_transparentColor then
begin
in_bitmap.Canvas.Pixels[x, y] := p or (in_transparency shl 24);
end
else
in_bitmap.Canvas.Pixels[x, y] := p or ($ff shl 24);
end;
end;
end;
{..............................................................................}
procedure alphaBlendTest(
const in_target : TCanvas;
const in_width : integer;
const in_height : integer);
const
BARSIZE = 30;
var
bitmap : TBitmap;
r : TRect;
blendFn : BLENDFUNCTION;
ret : Boolean;
begin
blendFn.BlendOp := AC_SRC_OVER;
blendFn.SourceConstantAlpha := $ff;
blendFn.BlendFlags := 0;
blendFn.alphaFormat := AC_SRC_ALPHA;
bitmap := TBitmap.Create;
try
bitmap.Width := in_width;
bitmap.Height := in_height;
bitmap.PixelFormat := pf32bit;
bitmap.HandleType := bmDIB;
bitmap.TransparentColor := clFuchsia;
bitmap.Transparent := true;
bitmap.Canvas.Brush.Color := clFuchsia;
bitmap.Canvas.FillRect(Bounds(0, 0, in_width, in_height));
bitmap.Canvas.Brush.Color := clGreen;
r := Bounds(
in_width div 2 - (in_width div 3) div 2,
0,
(in_width div 3) + 1,
BARSIZE + 1);
bitmap.Canvas.Rectangle(r);
// done drawing
//copyToAlpha(bitmap, clFuchsia, 1);
ret := Windows.TransparentBlt(
in_target.Handle,
0,
0,
in_width,
in_height,
bitmap.Canvas.Handle,
0,
0,
in_width,
in_height,
clFuchsia);
//blendFn);
ASSERT(ret);
finally
bitmap.Free;
end;
end;
{..............................................................................}
procedure TfrmMain.PaintBox1Paint(Sender: TObject);
var
r: TRect;
begin
PaintBox1.Canvas.Brush.Color := clBlue;
r := Bounds(0, 0, PaintBox1.ClientWidth, PaintBox1.ClientHeight);
PaintBox1.Canvas.FillRect(r);
PaintBox1.Canvas.Brush.Color := clRed;
PaintBox1.Canvas.Ellipse(0, 0, PaintBox1.ClientWidth, PaintBox1.ClientHeight);
alphaBlendTest(PaintBox1.Canvas, PaintBox1.ClientWidth, PaintBox1.ClientHeight);
end;
end.
y各ピクセルのr、g、bをあなたの望むアルファで置き換え、AlphaBlendのために255で割ります。もちろん、ピクセルのアルファをアルファ値に設定します。私は 'TransparentBlt'に関する質問を理解していませんが、透明性はどうですか? –
@Sertac OPには部分的に透明な色からなるビットマップがあります。透明部分は、宛先キャンバス上にそのまま残り、描画された部分は、宛先キャンバスにアルファベットで表示される。 – NGLN