gpt4 book ai didi

delphi - 创建透明的自定义位图画笔

转载 作者:行者123 更新时间:2023-12-03 14:49:04 29 4
gpt4 key购买 nike

问题定义

我正在尝试创建具有透明度的自定义位图画笔,但它似乎没有按预期工作。如果你看这个例子。添加代码并连接绘制、创建和销毁事件。

type
TForm3 = class(TForm)
procedure FormDestroy(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
private
FBitmap: TBitmap;
end;

// Implementation

function CreateBlockBitmap(const APenColor: TColor): TBitmap;
begin
Result := TBitmap.Create;
Result.Transparent := True;
Result.Canvas.Brush.Color := clWhite;
Result.Canvas.Brush.Style := bsClear;
Result.PixelFormat := pf32bit;
Result.SetSize(20, 20);
Result.Canvas.Brush.Color := APenColor;
Result.Canvas.Brush.Style := bsSolid;
Result.Canvas.FillRect(Rect(0,0,10,10));
end;

procedure TForm3.FormDestroy(Sender: TObject);
begin
FBitmap.Free;
end;

procedure TForm3.FormCreate(Sender: TObject);
begin
FBitmap := CreateBlockBitmap(clRed);
end;

procedure TForm3.FormPaint(Sender: TObject);
var
colNum: Integer;
rowNum: Integer;
begin
// Paint the rectangle using the brush
Canvas.Pen.Color := clGreen;
Canvas.Brush.Bitmap := FBitmap; // This is using bitmap
Canvas.Rectangle(50, 50, 250, 250);
// Draw the block using Canvas.Draw
for rowNum := 0 to 9 do
for colNum := 0 to 9 do
Canvas.Draw(350 + rowNum * 20, 50 + colNum * 20, FBitmap);
end;

此代码生成两个绘制的 block 。左侧是使用位图画笔绘制的,右侧是使用多次 Canvas.Draw 调用绘制的。

Brush Transparency

我需要将画笔涂成透明度,类似于使用阴影画笔时会发生的情况。这个答案似乎表明这是可能的:

How can I draw a patternBrush with transparent backround (GDI)?

我尝试过的

1) 我尝试使用纯色背景色而不是使用 bsClear。这只会使背景变白。

  Result.Canvas.Brush.Color := clWhite;
Result.Canvas.Brush.Style := bsSolid;

如果我使用clFuchsia,则颜色为紫红色。我还尝试绘制背景 clFuchsia,然后将 TransparentColor 设置为 clFuchsiaCanvas.Draw 选项以透明度进行绘制,而画笔则不然。

2)我尝试使用以下代码直接设置 Alpha channel :

procedure SetAlphaBitmap(const Dest: TBitmap;Color : TColor;Alpha:Byte);
type
TRGB32 = record
B, G, R, A: byte;
end;
PRGBArray32 = ^TRGBArray32;
TRGBArray32 = array[0..0] of TRGB32;
var
x, y: integer;
Line, Delta: integer;
ColorRGB : TColor;
begin
if Dest.PixelFormat<>pf32bit then exit;

ColorRGB := ColorToRGB(Color);
Line := integer(Dest.ScanLine[0]);
Delta := integer(Dest.ScanLine[1]) - Line;
for y := 0 to Dest.Height - 1 do
begin
for x := 0 to Dest.Width - 1 do
if TColor(RGB(PRGBArray32(Line)[x].R, PRGBArray32(Line)[x].G, PRGBArray32(Line)[x].B)) = ColorRGB then
PRGBArray32(Line)[x].A := Alpha;
Inc(Line, Delta);
end;
end;

然后在使用背景颜色绘制矩形后立即调用此例程。

  Result.Canvas.Brush.Style := bsSolid;
Result.Canvas.FillRect(Rect(0,0,10,10));
SetAlphaBitmap(Result, clBlack, 0); // Set the alpha channel
end;

我知道 Alpha channel 正在工作,因为如果我传入 255 的 Alpha 值,那么它也会在 Canvas.Draw 中显示为黑色。

  SetAlphaBitmap(Result, clBlack, 255);

3)我尝试通过创建图案画笔并指定它而不是位图来进行测试。这会产生完全相同的结果。 FBrush 是一个 HBRUSH。

  FBrush := CreatePatternBrush(FBitmap.Handle);

像这样设置画笔:

  Canvas.Brush.Handle := FBrush; 

4)我尝试按照上面的答案中所示调用 SetBkMode 。这根本没有什么区别。

  Canvas.Pen.Color := clGreen;
Canvas.Brush.Bitmap := FBitmap;
SetBkMode(Canvas.Handle, TRANSPARENT); // This doesn't make a difference
Canvas.Rectangle(50, 50, 250, 250);

编辑

5)我刚刚使用单色位图进行了测试,它也有同样的问题。该图像使用画笔绘制白色背景和黑色前景,并使用 Canvas.Draw 绘制透明图像。

function CreateMonochromeBitmap: TBitmap;
begin
Result := TBitmap.Create;
Result.Transparent := True;
Result.Canvas.Brush.Color := clWhite;
Result.Canvas.Brush.Style := bsSolid;
Result.PixelFormat := pf1bit;
Result.SetSize(20, 20);
Result.Canvas.Brush.Color := clBlack;
Result.Canvas.Brush.Style := bsSolid;
Result.Canvas.FillRect(Rect(0,0,10,10));
end;

在构造函数中:

FBitmap := CreateMonochromeBitmap;
FBrush := CreatePatternBrush(FBitmap.Handle);

在绘画中我们设置句柄而不是位图属性。

Canvas.Brush.Handle := FBrush; 

最佳答案

尝试在绘图循环之前将 Canvas 清除为空颜色。

Canvas.Clear(TAlphaColorRec.Null);

问候。保罗。

关于delphi - 创建透明的自定义位图画笔,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31467048/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com