我正在绘制具有不透明度(Alpha 透明度)能力的画布,如下所示:
var
Form1: TForm1;
IsDrawing: Boolean;
implementation
{$R *.dfm}
procedure DrawOpacityBrush(ACanvas: TCanvas; X, Y: Integer; AColor: TColor; ASize: Integer; Opacity: Byte);
var
Bmp: TBitmap;
I, J: Integer;
Pixels: PRGBQuad;
ColorRgb: Integer;
ColorR, ColorG, ColorB: Byte;
begin
Bmp := TBitmap.Create;
try
Bmp.PixelFormat := pf32Bit; // needed for an alpha channel
Bmp.SetSize(ASize, ASize);
with Bmp.Canvas do
begin
Brush.Color := clFuchsia; // background color to mask out
ColorRgb := ColorToRGB(Brush.Color);
FillRect(Rect(0, 0, ASize, ASize));
Pen.Color := AColor;
Pen.Style := psSolid;
Pen.Width := ASize;
MoveTo(ASize div 2, ASize div 2);
LineTo(ASize div 2, ASize div 2);
end;
ColorR := GetRValue(ColorRgb);
ColorG := GetGValue(ColorRgb);
ColorB := GetBValue(ColorRgb);
for I := 0 to Bmp.Height-1 do
begin
Pixels := PRGBQuad(Bmp.ScanLine[I]);
for J := 0 to Bmp.Width-1 do
begin
with Pixels^ do
begin
if (rgbRed = ColorR) and (rgbGreen = ColorG) and (rgbBlue = ColorB) then
rgbReserved := 0
else
rgbReserved := Opacity;
// must pre-multiply the pixel with its alpha channel before drawing
rgbRed := (rgbRed * rgbReserved) div $FF;
rgbGreen := (rgbGreen * rgbReserved) div $FF;
rgbBlue := (rgbBlue * rgbReserved) div $FF;
end;
Inc(Pixels);
end;
end;
ACanvas.Draw(X, Y, Bmp, 255);
finally
Bmp.Free;
end;
end;
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
case Button of
mbLeft:
begin
IsDrawing := True;
DrawOpacityBrush(Form1.Canvas, X, Y, clRed, 50, 85);
end;
end;
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if (GetAsyncKeyState(VK_LBUTTON) <> 0) and
(IsDrawing) then
begin
DrawOpacityBrush(Form1.Canvas, X, Y, clRed, 50, 85);
end;
end;
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
IsDrawing := False;
end;
绘制DrawOpacityBrush()
过程是 Remy Lebeau 对我最近提出的一个问题的更新:如何在具有透明度和不透明度的画布上绘画?
虽然这行得通,但结果并不符合我现在所需要的。
目前,每次DrawOpacityBrush()
在 MouseMove 中调用该过程时,它都会继续绘制画笔椭圆形状。这很糟糕,因为根据您在画布上移动鼠标的速度,输出并不像希望的那样。
希望这些示例图像可以更好地说明这一点:
-第一个红色画笔 我将鼠标从画布底部快速移动到顶部。
-第二个红色刷子我移动得慢了很多。
如您所见,不透明度已正确绘制,但圆圈也在不断重复绘制。
我希望它做的是:
(1)在椭圆周围画一条不透明线。
(2)可以选择完全阻止绘制任何椭圆。
这个模拟示例图像应该让我了解我希望如何绘制它:
3 条紫色画笔线显示选项 (1)。
为了实现选项(2),画笔线内的圆圈不应该在那里。
这应该让您在绘图时花些时间,而不是在画布上疯狂地移动鼠标以希望获得所需的结果。只有当您决定返回刚刚制作的笔触时,该区域的不透明度才会变得更暗等。
我怎样才能实现这些类型的绘图效果?
我希望能够绘制到 TImage 上,因为这就是我目前正在做的事情,因此将 TCanvas 作为函数或过程中的参数传递将是理想的。我还将为我的绘图使用 MouseDown、MouseMove 和 MouseUp 事件。
这是我使用 NGLN 提供的方法得到的输出:
不透明度似乎也适用于图像,它应该只是折线。