1

I want to draw a torus onto a given picture. The torus/ring itself should be drawn with transparency. Because there is no drawTorus, I use graphics path to get the result.

That's my code so far:

Image bmp = Bitmap.FromFile(Application.StartupPath + "\\background.jpg");
Graphics g = Graphics.FromImage(bmp);
g.SmoothingMode = SmoothingMode.AntiAlias;

Rectangle r1 = new Rectangle(bmp.Width / 2 - bmp.Height / 2, 0, bmp.Height, bmp.Height);
Rectangle r2 = Rectangle.Inflate(r1, -50, -50);

GraphicsPath p1 = new GraphicsPath();
p1.AddEllipse(r1);
GraphicsPath p2 = new GraphicsPath();
p1.AddEllipse(r2);

Region re = new Region(p1);
re.Xor(p2);

g.FillRegion(new SolidBrush(Color.FromArgb(80,0,0,0)),re);
g.Save();

The result looks like this: Result image

The problem with this is, that SmoothingMode is ignored. You can see it here: enter image description here

I've read that this is because Regions aren't affected by the SmoothingMode parameter.

But how to fix it?

  1. Is there an other way to write the code above without regions?
  2. I read about AlphaMasking over here , but this also won't work, because it would influence the transparency of the torus, too.
Community
  • 1
  • 1
netblognet
  • 1,951
  • 2
  • 20
  • 46
  • 1
    Had the same problem a while ago, i'll try to find my solution. – AntiHeadshot Jan 19 '16 at 09:16
  • 3
    A region is supposed to help answer the question "is this pixel inside or outside the region", and thus only supports yes/no answers. It does not support "it is on the edge and therefore halfway inside and halfway outside" thus giving you room to calculate an alpha mask for those pixels. The *path*, however, is different and if you drop going to a region and only deals with the path you should be able to handle it. – Lasse V. Karlsen Jan 19 '16 at 09:39
  • @LasseV.Karlsen thanks for clearing thing up. I misunderstood the concept of Region and underestimated the possibilitys of GraphicsPaths. Thanks! – netblognet Jan 19 '16 at 09:41

1 Answers1

1

Use FillPath and your problem should be solved.

GraphicsPath path = new GraphicsPath();
path.AddEllipse(r1);
path.AddEllipse(r2);

using(Brush b = new SolidBrush(Color.FromArgb(80,0,0,0)))
    g.FillPath(b, path);
AntiHeadshot
  • 1,130
  • 9
  • 24
  • Wow! That was just to easy... I had not thought, that fillPath knows that it has to fill the area between the both ellipses. Therefore I used the Regions and XOr. – netblognet Jan 19 '16 at 09:39
  • It is checking for uneven crossings, so adding a third circle will fill the third one again. [Here](https://msdn.microsoft.com/en-us/library/system.windows.media.pathgeometry.fillrule%28v=vs.110%29.aspx) you will find more about it. – AntiHeadshot Jan 19 '16 at 09:56