gpt4 book ai didi

Delphi Graphics32 在图层上绘制透明椭圆

转载 作者:行者123 更新时间:2023-12-03 15:28:41 25 4
gpt4 key购买 nike

我希望能够在 ImgView32 的透明图层上绘制一个空的椭圆。知道怎么做吗?到目前为止我能想到的是:

 BL := TBitmapLayer.Create(ImgView.Layers);
BL.Bitmap.DrawMode := dmTransparent;
BL.Bitmap.SetSize(imwidth,imheight);
BL.Bitmap.Canvas.Pen.Width := penwidth;
BL.Bitmap.Canvas.Pen.Color := pencolor;
BL.Location := GR32.FloatRect(0, 0, imwidth, imheight);
BL.Scaled := False;
BL.OnMouseDown := LayerMouseDown;
BL.OnMouseUp := LayerMouseUp;
BL.OnMouseMove := LayerMouseMove;
BL.OnPaint := LayerOnPaint;

...
BL.Bitmap.Canvas.Pen.Color := clBlue;
BL.Bitmap.Canvas.MoveTo(FStartPoint.X, FStartPoint.Y);
BL.Bitmap.Canvas.Ellipse(FStartPoint.X, FStartPoint.Y,FEndPoint.X, FEndPoint.Y);

起点和终点是通过鼠标事件获取的。

我实际上正在尝试绘制一个动态椭圆(在鼠标事件上)。所以就涉及到onMouseDown(LayerMouseDown)、onMouseUp(LayerMouseUp)和OnMouseMove(LayerMouseMove)事件。作为引用,请检查此 question ,它处理动态绘制线条。我想做同样的事情,但用椭圆而不是直线。

因此,我没有 AddLineToLayer,而是使用 AddCircleToLayer 过程现在的事件如下所示:

procedure TForm5.SwapBuffers32;
begin
TransparentBlt(
BL.Bitmap.Canvas.Handle, 0, 0, BL.Bitmap.Width, BL.Bitmap.Height,
bm32.Canvas.Handle, 0, 0, bm32.Width, bm32.Height, clWhite);
end;

procedure TForm5.ImgViewResize(Sender: TObject);
begin
OffsX := (ImgView.ClientWidth - imwidth) div 2;
OffsY := (ImgView.ClientHeight - imheight) div 2;
BL.Location := GR32.FloatRect(OffsX, OffsY, imwidth+OffsX, imheight+OffsY);
end;

procedure TForm5.LayerMouseDown(Sender: TObject; Buttons: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
FStartPoint := Point(X-OffsX, Y-OffsY);
FDrawingLine := true;
end;

procedure TForm5.LayerMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
if FDrawingLine then
begin
SwapBuffers32;
if RadioGroup1.ItemIndex=0 then
begin
BL.Bitmap.Canvas.Pen.Color := pencolor;
BL.Bitmap.Canvas.MoveTo(FStartPoint.X, FStartPoint.Y);
BL.Bitmap.Canvas.LineTo(X-OffsX, Y-OffsY);
end
else
begin
BL.Bitmap.Canvas.Pen.Color := pencolor;
BL.Bitmap.Canvas.MoveTo(FStartPoint.X, FStartPoint.Y);
SwapBuffers32;
BL.Bitmap.Canvas.Ellipse(FStartPoint.X, FStartPoint.Y,X-OffsX, Y-OffsY);
end;
end;
end;

procedure TForm5.LayerMouseUp(Sender: TObject; Buttons: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if RadioGroup1.ItemIndex=0 then
begin
FDrawingLine := false;
FEndPoint := Point(X-OffsX, Y-OffsY);
AddLineToLayer;
SwapBuffers32;
end
else
begin
FDrawingLine := false;
FEndPoint := Point(X-OffsX, Y-OffsY);
AddCircleToLayer;
SwapBuffers32;
end
end;

procedure TForm5.LayerOnPaint(Sender: TObject; Buffer: TBitmap32);
begin
SwapBuffers32;
end;

procedure TForm5.AddLineToLayer;
begin
bm32.Canvas.Pen.Color := pencolor;
bm32.Canvas.Pen.Width := penwidth;
bm32.Canvas.MoveTo(FStartPoint.X, FStartPoint.Y);
bm32.Canvas.LineTo(FEndPoint.X, FEndPoint.Y);
end;

procedure TForm5.AddCircleToLayer;
begin
bm32.Canvas.Pen.Color := pencolor;
bm32.Canvas.Pen.Width := penwidth;
bm32.Canvas.MoveTo(FStartPoint.X, FStartPoint.Y);
bm32.Canvas.Ellipse(FStartPoint.X, FStartPoint.Y,FEndPoint.X, FEndPoint.Y);
SwapBuffers32;
end;

但是当我使用这段代码时,圆圈(椭圆)被白色填充(就像在这张图片中一样) enter image description here直到我开始绘制下一个椭圆(因此 onMouseMove 和 onMouseUp 椭圆被填充)。只有当我再执行一次 onMouseDown 时,之前的圆圈就会被清空,但新的椭圆也被白色填充(就像在这张图片中一样) enter image description here

此外,如果您尝试一个接一个地制作更多的省略号,并在较旧的省略号的顶部,您会注意到会有 onMouseMove 省略号的痕迹,如下图所示:

enter image description here

所以这段代码一定是我遗漏了一些东西。

请帮我解决这个问题。

最佳答案

如果您使用的是主干中最新的 GR32 代码,您还可以使用此代码片段来定义椭圆

Points := Ellipse(Center.X, Center.Y, Radius.X, Radius.Y);

或者更简单

Points := Ellipse(Center, Radius);

其中Points定义为

Points: TArrayOfFloatPoint;

这会生成一个椭圆形多边形,其中心位于Center,独立的 x 和 y 相关半径由 Radius 定义。

获得多边形后,您可以使用任何矢量渲染器渲染它。例如,您可以使用内置的 VPR 渲染器

PolygonFS(Bitmap, Points, SomeColor32);

渲染一个填充的椭圆。

但是,如果您只想渲染帧,则可以使用此

PolylineFS(Bitmap, Points, AnotherColor32, True, PenWidth);

其参数是

  1. Bitmap = 要渲染到的 TBitmap32 实例
  2. 点 = 多边形点(如上定义)
  3. AnotherColor32 = 颜色,用于渲染
  4. True = 闭合多边形(否则椭圆在起点和终点之间会有间隙
  5. PenWidth = 框架的宽度

如果您愿意,您也可以在一次调用中渲染它,例如

PolylineFS(Bitmap, Ellipse(Center, Radius), AnotherColor32, True, PenWidth);

为了获得任意(旋转)椭圆,您需要在渲染之前变换多边形。您可以使用

TransformPolygon(Points, Transformation);

为此,它获取一个 TTransformation 实例作为第二个参数。这可以包括所有常见操作,例如旋转、倾斜、缩放和平移。

如果您使用此功能,您还可以从一个更简单的圆开始作为多边形输入,然后缩放圆以生成椭圆形。

上面的代码需要将单元 GR32_VectorUtils、GR32_Polygons 包含到您的项目中,例如

uses
GR32_VectorUtils, GR32_Polygons;

优点是您不依赖 GDI 进行渲染,因此您可以从 GR32 的可用渲染器中选择渲染器。有些包括类似 ClearType 的效果并提高 LCD 屏幕上的可视性。更不用说抗锯齿质量和控制渲染 Gamma 的能力。

关于Delphi Graphics32 在图层上绘制透明椭圆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28570792/

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