加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 在ImgView32图层上绘制粗虚线

发布时间:2020-12-15 09:30:28 所属栏目:大数据 来源:网络整理
导读:我只想在ImgView32中的一个图层上绘制一条垂直虚线粗线. 我还希望我的线条更粗,所以我绘制了多条彼此靠近的线条,因为Canvas.Pen.Width对LineTo方法没有影响. 所以我的代码如下: procedure TMainForm.PaintDottedHandler(Sender: TObject;Buffer: TBitmap32)
我只想在ImgView32中的一个图层上绘制一条垂直虚线粗线.
我还希望我的线条更粗,所以我绘制了多条彼此靠近的线条,因为Canvas.Pen.Width对LineTo方法没有影响.
所以我的代码如下:

procedure TMainForm.PaintDottedHandler(Sender: TObject;Buffer: TBitmap32);
var
  Cx,Cy,raza: Single;
  W2,H2: Single;
  I,J: Integer;
  points:TArrayOfFloatPoint;
  Center,Radius:TFloatPoint;
const
  CScale = 1 / 200;
begin

  if Sender is TPositionedLayer then
    with TPositionedLayer(Sender).GetAdjustedLocation do
    begin
      W2 := (Right - Left) * 0.5;
      H2 := (Bottom - Top) * 0.5;

      Cx := Left + W2;
      Cy := Top + H2;
      W2 := W2 * CScale;
      H2 := H2 * CScale;
      Buffer.PenColor := clRed32;

      Buffer.MoveToF(Cx-2,Top);
      Buffer.LineToFSP(Cx-2,Bottom);

      Buffer.MoveToF(Cx-1,Top);
      Buffer.LineToFSP(Cx-1,Bottom);

      Buffer.MoveToF(Cx,Top);
      Buffer.LineToFSP(Cx,Bottom);

      Buffer.MoveToF(Cx+1,Top);
      Buffer.LineToFSP(Cx+1,Bottom);

      Buffer.MoveToF(Cx+2,Top);
      Buffer.LineToFSP(Cx+2,Bottom);
    end;
end;

因此,该线旨在放置在新图层的中间.我使用这个添加图层:

procedure TMainForm.DottedLine1Click(Sender: TObject);
var
  L: TPositionedLayer;
begin
  L := CreatePositionedLayer;
  L.OnPaint := PaintDottedHandler;
  L.Tag := 2;
  Selection := L;
end;

对于其余的代码,只需将我的代码添加到图层示例中,您就可以重现我的问题.

据我所知,为了绘制虚线,有多个aprroaches,如带有LineToFSP的Stipple(在我的代码中使用)或带有BuildDashedLine点的PolyPolygonFS.但我似乎无法让他们中的任何一个工作.
实际上第二种方法没有做任何事情……所以我坚持第一种方法.
因此,似乎每次它开始绘制一条线时,它就像虚线开始一样随机.所以它既可以是像素,也可以是空像素.
因此,当我调整图层大小时,线条会变换,如下图所示:

事实上,我想要实现的是:

当然,我希望在调整图层大小时再次绘制线条而不会扭曲它(这就是我使用onPaint处理程序方法的原因).
如果我只是在一个图层上绘制一条简单的线条(使用Bitmap.Canvas),然后调整图层大小,那么就像拉伸jpeg一样,这条线会变形,所以我想避免这种情况.

请告诉我如何在ImgView32(TGraphics32)的图层上绘制粗虚线

编辑

在尝试了答案中的代码之后我就开始了.然而,这个层有一个副作用:当调整图层大小(使用鼠标)时,在某些宽度处,虚线的颜色会变暗并模糊如下:

在调整大小之前

调整大小后(有时).

您可以使用相同的代码自行重现.

编辑

这个特殊图层还有另一个问题:将其保存到文件中…我尝试使用2种方法将其保存为透明PNG但我不断收到损坏的文件.即使我尝试将图层保存为Bitmap,也会发生相同的损坏.请查看这个问题:

Graphics32 – saving transparent drawing layer to png

解决方法

正如@SpeedFreak所提到的,你需要在每一行绘制调用之前重置StrippleCounter.您还需要为您的生产线设置正确的线条图案.这可以通过SetStripple方法完成.诀窍是正确设置此图案的宽度.如果您的线宽为5像素,那么您需要一个由5个黑色像素和5个白色像素组成的图案.

试试这个,我删除了不必要的代码(更新):

procedure TMainForm.PaintDottedHandler(Sender: TObject; Buffer: TBitmap32);
var
  R: TRect;
  Cx: Integer;
begin
  if Sender is TPositionedLayer then
  begin
    // Five black pixels,five white pixels since width of the line is 5px
    Buffer.SetStipple([clBlack32,clBlack32,clWhite32,clWhite32]);
    // We mest operate on integer values to avoid blurred line.
    R := MakeRect(TPositionedLayer(Sender).GetAdjustedLocation);
    Cx := R.Left + (R.Right - R.Left) div 2;

    Buffer.StippleCounter := 0;
    Buffer.MoveToF(Cx-2,R.Top);
    Buffer.LineToFSP(Cx-2,R.Bottom);

    Buffer.StippleCounter := 0;
    Buffer.MoveToF(Cx-1,R.Top);
    Buffer.LineToFSP(Cx-1,R.Bottom);

    Buffer.StippleCounter := 0;
    Buffer.MoveToF(Cx,R.Top);
    Buffer.LineToFSP(Cx,R.Bottom);

    Buffer.StippleCounter := 0;
    Buffer.MoveToF(Cx+1,R.Top);
    Buffer.LineToFSP(Cx+1,R.Bottom);

    Buffer.StippleCounter := 0;
    Buffer.MoveToF(Cx+2,R.Top);
    Buffer.LineToFSP(Cx+2,R.Bottom);
  end;
end;

结果应该如下图所示:

在调整图层大小时,您不时会出现“模糊”线条的原因是因为您正在使用浮点值绘制线条.您需要使用整数值.我猜测在某些情况下,当你的线只填充那个像素的一部分时,绘制引擎决定绘制一个模糊的像素.

希望这可以帮助.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读