GraphicsPath和DrawPath - 删除相交线

时间:2015-03-10 11:50:42

标签: c# .net gdi+ gdi graphicspath

以下代码绘制了一个十字架:

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);
    }
}

enter image description here

我想这样绘制:

enter image description here

我已尝试使用Flatten();CloseAllFigures();,但这些都无法使用。

我正在寻找像Union这样的效果:

enter image description here

这可以使用GraphicsPath吗?

4 个答案:

答案 0 :(得分:1)

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

        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);
                }
            }
        }

结果如下:

This is the result

答案 1 :(得分:1)

可以使用Regions.But如果没有其他解决方案,你应该使用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 :(得分:0)

这是可能的,你所追求的是区域。看看:

Regions in GDI+

我猜你的下一步是概述这个地区。这是困难的部分,因为没有API可以做到这一点。最简单的方法是:

  • 使用更粗笔在第一张图片中绘制所有内容。
  • 在路径和联合结果区域之外创建区域。
  • 填写或删除生成的联合区域(有API)。

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

答案 3 :(得分:0)

您需要使用区域,这是一个根据您现有代码改编的示例。应该注意的是,您还可以在该区域调用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);
    }