이 질문은 내에서 earlier question과 관련이 있습니다.Alphablend 및 TransparentBlt
소스 레이어의 특정 부분에만 적용되는 알파로 두 개의 레이어를 결합하고 싶습니다. 필자가 시도한 한 가지 방법은 SourceConstantAlpha를 $ ff로 설정하는 것 (그리고 소스 레이어에서 알파 채널을 사용하는 기능을 가짐)입니다.
이런 종류의 작품 - 느리지 만 (내가 ScanLines를 사용하여 속도를 높일 수있을 것 같지만), 알파 채널을 설정할 대상을 알 수 없다는 것이 부분입니다.
st.Red = Src.Red + (1 - Src.Alpha) * Dst.Red
내가 추측 작업에 의해 몇 가지 다른 값을 시도,하지만 내 첫 번째 질문은 다음과 같습니다 : 나는 알파 값을 계산하려면 어떻게 문서는 계산이 제안?
몇 가지 다른 질문을 읽은 후에 투명성이 아니라 잘 마스킹하는 TransparentBlt 기능을 사용하여이 두 가지 호출을 함께 사용하는 방법이 있습니다 (어쩌면 세 번째 레이어 사용).)?
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