简体   繁体   English

用C#轻松画出空心圆环形状的任何方法

[英]Any way to easily draw a hollow donut shape in C#

So like a graphics.FillEllipse, but with a hole in the middle. 所以就像一个graphics.FillEllipse,但中间有一个洞。 I need to highlight some circular icons by putting a ring around them, and due to the constraints of the larger program it's hard/impossible to simply FillEllipse under them to make it look like there's a hole. 我需要通过在它们周围放置一个环来突出显示一些圆形图标,并且由于较大程序的限制,很难/不可能简单地将FillEllipse放在它们下面以使它看起来像是一个洞。

// Create a brush
SolidBrush b = new SolidBrush(Color.Blue);

// Clear your Graphics object (defined externally)
gfx.Clear(Color.White);

// You need a path for the outer and inner circles
GraphicsPath path1 = new GraphicsPath();
GraphicsPath path2 = new GraphicsPath();

// Define the paths (where X, Y, and D are chosen externally)
path1.AddEllipse((float)(X - D / 2), (float)(Y - D / 2), (float)D, (float)D);
path2.AddEllipse((float)(X - D / 4), (float)(Y - D / 4), (float)(D / 2), (float)(D / 2));

// Create a region from the Outer circle.
Region region = new Region(path1);

// Exclude the Inner circle from the region
region.Exclude(path2);

// Draw the region to your Graphics object
gfx.FillRegion(b, region);

Using GDI+, you can draw a circle with a high value for the pen width, to make it look like a donut. 使用GDI +,您可以绘制一个具有较高笔宽的圆圈,使其看起来像甜甜圈。 There will be nothing in the centre so you'll be able to see through it. 中心没有任何东西,所以你将能够看透它。

You could create a Region that is based on what you would have drawn using the FillEllipse and the use the Exclude method of the Region to remove areas that you don't want by using another GraphicsPath returned from another call to FillEllipse. 您可以创建一个区域,该区域基于您使用FillEllipse绘制的内容,并使用Region的Exclude方法通过使用另一个对FillEllipse的调用返回的另一个GraphicsPath来删除您不想要的区域。

Then you would just have to overlay the resulting Region on top of what you want it to surround. 然后,您只需将结果区域覆盖在您想要它所包围的内容之上。

Based on user263134 answer: 基于user263134的回答:

    g.FillRegion(Brushes.Black, GetRingRegion(center, innerRadius, outherRadius));

    public static RectangleF GetRectangle(PointF center, float radius)
    {
        var rectangle = new RectangleF(center.X - radius, center.Y - radius,radius * 2, radius * 2);
        return rectangle;
    }

    public static Region GetRingRegion(PointF center, float innerRadius, float outherRadius)
    {
        // You need a path for the outer and inner circles
        var path1 = new GraphicsPath();
        var path2 = new GraphicsPath();

        // Define the paths (where X, Y, and D are chosen externally)
        path1.AddEllipse(GetRectangle(center,outherRadius));
        path2.AddEllipse(GetRectangle(center, innerRadius));

        // Create a region from the Outer circle.
        Region region = new Region(path1);

        // Exclude the Inner circle from the region
        region.Exclude(path2);

        return region;
    }

The answer of 'sth' is pretty much what you need, but dude you can easily just use: (Graphics).DrawEllipse(new Pen(YOURCOLOR, RINGDIAMETER), center.x - radius, center.y - radius, radius * 2, radius * 2); 'sth'的答案几乎就是你所需要的,但是老兄,你可以轻松地使用:(图形).DrawEllipse(新笔(YOURCOLOR,RINGDIAMETER),center.x - radius,center.y - radius,radius * 2 ,radius * 2); But i think you knew this before. 但我想你以前就知道这一点。 :) :)

One important thing with the answer from sth, which is the most flexible answer, is that GraphicsPath and Brush need to be disposed so put their declaration in a using statement as follows: 一个重要的问题是,回答是什么,这是最灵活的答案,是需要处理GraphicsPath和Brush,所以将它们的声明放在using语句中,如下所示:

// Clear your Graphics object (defined externally)
gfx.Clear(Color.White);

// You need a path for the outer and inner circles
using (GraphicsPath path1 = new GraphicsPath(), path2 = new GraphicsPath())
  {
  // Define the paths (where X, Y, and D are chosen externally)
  path1.AddEllipse((float)(X - D / 2), (float)(Y - D / 2), (float)D, (float)D);
  path2.AddEllipse((float)(X - D / 4), (float)(Y - D / 4), (float)(D / 2), (float)(D / 2));

  // Create a region from the Outer circle.
  Region region = new Region(path1);

  // Exclude the Inner circle from the region
  region.Exclude(path2);

  // Create a brush
  using (SolidBrush b = new SolidBrush(Color.Blue))
    {
    // Draw the region to your Graphics object
    gfx.FillRegion(b, region);
    }
  }

This will ensure that they are disposed when they are no longer needed. 这将确保在不再需要时将其丢弃。

The using is the best way to ensure that the Dispose method is called even when an exception occurs. 使用是确保即使发生异常也会调用Dispose方法的最佳方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM