首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用填充图案填充多边形的Graphics32

使用填充图案填充多边形的Graphics32
EN

Stack Overflow用户
提问于 2017-07-26 13:52:09
回答 2查看 614关注 0票数 2

我正在尝试将一个delphi XE4应用程序转换为使用Graphics32库进行绘图,而不是使用标准的delphi绘图方法。

我做的一件事是绘制一个图标,其中包含一个带有对角线交叉阴影图案的小椭圆。图标应如下所示:

下面是我如何使用标准的TCanvas绘图方法来实现这一点:

代码语言:javascript
复制
ACanvas.Brush.Color := shape.pcolor;
ACanvas.Brush.Style := bsdiagCross;
ACanvas.Ellipse(-13, -9, 13, 9);

我可以用Graphics32绘制一个椭圆,执行以下操作:

代码语言:javascript
复制
var    
  Polygon : TArrayOfFloatPoint;   
begin    
  Polygon := Ellipse(0, 0, 13, 9);
  PolylineFS(Bitmap, Polygon, pcolor, True, UAVPenWidth);

但是,有没有一种简单的方法来复制对角线交叉阴影图案?我假设我可以使用TBitmapPolygonFiller类,但这是使用位图填充的。请注意,此绘图指向其OnPaint事件处理程序中的TPositionedLayer (如果相关)。

EN

Stack Overflow用户

回答已采纳

发布于 2017-07-28 00:41:33

到目前为止,Graphics32中没有直接的模式支持,但是有几十种方法可以创建您想要使用的模式。

下面是一个使用样例多边形填充的解决方案:

首先,您需要为阴影图案编写一个采样器类。有几种方法可以构建这样的采样器。下面你可以找到一个非常简单的例子:

代码语言:javascript
复制
type
  THatchedPatternSampler = class(TCustomSampler)
  public
    function GetSampleInt(X, Y: Integer): TColor32; override;
  end;

function THatchedPatternSampler.GetSampleInt(X, Y: Integer): TColor32;
begin
  Result := 0;
  if ((X - Y) mod 8 = 0) or ((X + Y) mod 8 = 0) then
    Result := clRed32
end;

你只需要在这里覆盖一个方法(GetSampleInt),所有其他的方法都可以从祖先类中使用。

现在它有点卷积了。为了使用该示例,您必须将其用于TSamplerFiller之上,如下所示:

代码语言:javascript
复制
Sampler := THatchedPatternSampler.Create;
Filler := TSamplerFiller.Create(Sampler);

一旦你有了这个填充物,你就可以在PolygonFS甚至PolylineFS中使用它。

最后,代码可能如下所示:

代码语言:javascript
复制
var
  Polygon: TArrayOfFloatPoint;
  Sampler: THatchedPatternSampler;
  Filler: TSamplerFiller;
begin
  Polygon := Ellipse(128, 128, 120, 100);
  Sampler := THatchedPatternSampler.Create;
  try
    Filler := TSamplerFiller.Create(Sampler);
    try
      PolygonFS(PaintBox32.Buffer, Polygon, Filler);
    finally
      Filler.Free;
    end;
      finally
    Sampler.Free;
  end;

  PolylineFS(PaintBox32.Buffer, Polygon, clRed32, True, 1);
end;

这将在位图(这里: TPaintBox32实例的缓冲区)的中心绘制一个相当大的椭圆,并用带阴影的采样器代码填充它。最后,使用PolylineFS函数绘制一个实心轮廓。

从性能的角度来看,这不是最快的方法,因为GetSampleInt是按像素调用的。然而,这是最容易理解所发生的事情。

对于更快的替代方法,您应该直接使用填充物。您可以像这样直接从TCustomPolygonFiller派生:

代码语言:javascript
复制
type
  THatchedPatternFiller = class(TCustomPolygonFiller)
  private
    procedure FillLine(Dst: PColor32; DstX, DstY, Length: Integer; AlphaValues: PColor32);
  protected
    function GetFillLine: TFillLineEvent; override;
  end;

其中,方法GetFillLine变得非常简单:

代码语言:javascript
复制
function THatchedPatternFiller.GetFillLine: TFillLineEvent;
begin
  Result := FillLine;
end;

但是,FillLine方法会稍微复杂一些,如下所示:

代码语言:javascript
复制
procedure THatchedPatternFiller.FillLine(Dst: PColor32; DstX, DstY,
  Length: Integer; AlphaValues: PColor32);
var
  X: Integer;
begin
  for X := DstX to DstX + Length do
  begin
    if ((X - DstY) mod 8 = 0) or ((X + DstY) mod 8 = 0) then
      Dst^ :=clRed32
    else
      Dst^ := 0;

    Inc(Dst);
  end;
end;

由于DstY保持不变,您还可以重构代码以提高性能。或者,您可以使用汇编程序(SSE)来加速代码,但我猜对于这样一个简单的函数来说,这样做太夸张了。

票数 3
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45318436

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档