【问题标题】:GraphicsPath and DrawPath - Removing Intersecting LinesGraphicsPath 和 DrawPath - 删除相交的线
【发布时间】:2015-05-11 20:21:38
【问题描述】:

以下代码画了一个十字:

using (SolidBrush brush = new SolidBrush(Color.FromArgb(192, 99, 104, 113)))
{
    using(GraphicsPath path = new GraphicsPath())
    {
        path.AddRectangle(new Rectangle(e.ClipRectangle.X + (e.ClipRectangle.Width - 40) / 2, e.ClipRectangle.Y, 40, e.ClipRectangle.Height));
        path.AddRectangle(new Rectangle(e.ClipRectangle.X, e.ClipRectangle.Y + (e.ClipRectangle.Height - 40) / 2, e.ClipRectangle.Width, 40));
        path.FillMode = FillMode.Winding;
        e.Graphics.DrawPath(Pens.DimGray, path);
    }
}

我想画成这样:

我尝试过使用Flatten();CloseAllFigures();,但这些都不起作用。

我正在寻找类似 Union 的效果:

GraphicsPath 可以做到这一点吗?

【问题讨论】:

    标签: c# .net gdi+ gdi graphicspath


    【解决方案1】:

    可以使用Regions。但是如果没有其他解决方案,你应该使用GDI中的API FrameRgn来绘制区域的框架。

            Graphics g = e.Graphics;
            using (SolidBrush brush = new SolidBrush(Color.FromArgb(192, 99, 104, 113)))
            {
                using (GraphicsPath path = new GraphicsPath())
                {
                    path.AddRectangle(new Rectangle(e.ClipRectangle.X + (e.ClipRectangle.Width - 40) / 2, e.ClipRectangle.Y, 40, e.ClipRectangle.Height));
                    path.AddRectangle(new Rectangle(e.ClipRectangle.X, e.ClipRectangle.Y + (e.ClipRectangle.Height - 40) / 2, e.ClipRectangle.Width, 40));
                    path.FillMode = FillMode.Winding;
                    using (Region region = new Region(path))
                    {
                        IntPtr reg = region.GetHrgn(g);
                        IntPtr hdc = g.GetHdc();
                        IntPtr brushPtr = Win32.GetStockObject(Win32.WHITE_BRUSH);
                        IntPtr oldbrushPtr = Win32.SelectObject(hdc, brushPtr);
                        Win32.FrameRgn(hdc, reg, brushPtr, 1, 1);
                        Win32.DeleteObject(brushPtr);
                        Win32.SelectObject(hdc, oldbrushPtr);
                        region.ReleaseHrgn(reg);
                        g.ReleaseHdc();
                    }
                }
            }
    

    【讨论】:

      【解决方案2】:

      我知道这不是一个完美的解决方案,但将其作为一种选择:

              using (SolidBrush brush = new SolidBrush(Color.FromArgb(192, 99, 104, 113)))
              {
                  using (GraphicsPath path = new GraphicsPath())
                  {
                      var rect1 = new Rectangle(e.ClipRectangle.X + (e.ClipRectangle.Width - 40) / 2, e.ClipRectangle.Y, 40, e.ClipRectangle.Height - 1);
                      var rect2 = new Rectangle(e.ClipRectangle.X, e.ClipRectangle.Y + (e.ClipRectangle.Height - 40) / 2, e.ClipRectangle.Width - 1, 40);
                      path.AddRectangle(rect1);
                      path.AddRectangle(rect2);
                      e.Graphics.DrawPath(Pens.DimGray, path);
      
                      var bgRect1 = new Rectangle(rect1.X + 1, rect1.Y + 1, rect1.Width - 1, rect1.Height - 1);
                      var bgRect2 = new Rectangle(rect2.X + 1, rect2.Y + 1, rect2.Width - 1, rect2.Height - 1);
                      using (GraphicsPath backgroundPath = new GraphicsPath())
                      {
                          backgroundPath.AddRectangle(bgRect1);
                          backgroundPath.AddRectangle(bgRect2);
                          e.Graphics.FillPath(Brushes.White, backgroundPath);
                      }
                  }
              }
      

      这是结果:

      【讨论】:

        【解决方案3】:

        这是可能的,您所追求的是地区。看看:

        Regions in GDI+

        我猜您的下一步是勾勒该地区的轮廓。这是困难的部分,因为没有 API 可以做到这一点。最简单的方法是:

        • 笔画出你在第一张照片中所做的一切。
        • 从路径中创建区域并合并结果区域。
        • 填充或删除生成的联合区域(有相应的 API)。

        这将生成您附加的第二张图片。由于缺少边缘检测、轮廓或区域到路径 API 来帮助您绘制结果,因此区域操作需要一点创造力。

        【讨论】:

          【解决方案4】:

          您需要为此使用区域,这里是根据您现有代码改编的示例。需要注意的是,你也可以在区域上调用Exclude、Intersect和Xor! :)

              private void Form1_Paint(object sender, PaintEventArgs e)
              {
                  GraphicsPath Shape1 = new GraphicsPath();
                  Shape1.AddRectangle(new Rectangle(e.ClipRectangle.X + (e.ClipRectangle.Width - 40) / 2, e.ClipRectangle.Y, 40, e.ClipRectangle.Height));
          
                  GraphicsPath Shape2 = new GraphicsPath();
                  Shape2.AddRectangle(new Rectangle(e.ClipRectangle.X, e.ClipRectangle.Y + (e.ClipRectangle.Height - 40) / 2, e.ClipRectangle.Width, 40));
          
                  Region UnitedRegion = new Region();
                  UnitedRegion.MakeEmpty();
                  UnitedRegion.Union(Shape1);
                  UnitedRegion.Union(Shape2);
          
                  e.Graphics.FillRegion(Brushes.Black, UnitedRegion);
              }
          

          【讨论】:

            猜你喜欢
            • 2010-10-04
            • 1970-01-01
            • 2017-02-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-11-23
            • 2011-05-25
            • 1970-01-01
            相关资源
            最近更新 更多