问题
Ive got a panel
and im drawing a heart on that panel
..
But i dont want to draw the heart i want to draw everything except the heart so the heart is transparent.
Can i invert the Region
selected out of the Path
?
System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath();
path.AddArc(0, 0, (this.Width / 2), (this.Height / 2), 135, 195);
path.AddArc((this.Width / 2), 0, (this.Width / 2), (this.Height / 2), 210, 195);
path.AddLine((this.Width / 2), this.Height, (this.Width / 2), this.Height);
this.Region = new Region(path);
this.BackColor = Color.Black;
What it looks like(white = transparent):

What i want it to look like(white = transparent):

回答1:
I think you can just add 2 graphics paths together.
You could try this code out:
private void panel1_Paint(object sender, PaintEventArgs e)
{
GraphicsPath path = new GraphicsPath();
path.AddArc(0, 0, (this.Width / 2), (this.Height / 2), 135, 195);
path.AddArc((this.Width / 2), 0, (this.Width / 2), (this.Height / 2), 210, 195);
path.AddLine((this.Width / 2), this.Height, (this.Width / 2), this.Height);
GraphicsPath path2 = new GraphicsPath();
path2.AddRectangle(new Rectangle(new Point(0, 0), panel1.Size));
path2.AddPath(path, false);
e.Graphics.FillPath(Brushes.Black, path2);
}
Result is:

回答2:
You can try excluding a region from from the Graphic object of your panel's Paint event:
GraphicsPath path = new GraphicsPath();
path.AddArc(0, 0, (this.Width / 2), (this.Height / 2), 135, 195);
path.AddArc((this.Width / 2), 0, (this.Width / 2), (this.Height / 2), 210, 195);
path.AddLine((this.Width / 2), this.Height, (this.Width / 2), this.Height);
using (Region r = new Region(path)) {
e.Graphics.ExcludeClip(r);
}
// continue drawing...
e.Graphics.Clear(Color.Yellow);
or if trying to modify the control's region, then just use the Region's Exclude property:
GraphicsPath path = new GraphicsPath();
path.AddArc(0, 0, (this.Width / 2), (this.Height / 2), 135, 195);
path.AddArc((this.Width / 2), 0, (this.Width / 2), (this.Height / 2), 210, 195);
path.AddLine((this.Width / 2), this.Height, (this.Width / 2), this.Height);
Region r = new Region(new Rectangle(Point.Empty, this.ClientSize));
r.Exclude(path);
this.Region = r;
回答3:
I don't know of a way to invert the selection, but you can always draw a heart in the background color, then change the background color to black.
this.BackColor = Form.BackColor;
Form.BackColor = Color.Black;
回答4:
Original solution here. I've modified that for your needs
this.Region = InvertRegion(new Region(path), this.Width, this.Height);
and
private Region InvertRegion(Region region, int width, int height)
{
Bitmap mask = new Bitmap(width, height);
Graphics.FromImage(mask).FillRegion(Brushes.Black, region);
int matchColor = Color.Black.ToArgb();
Region inverted = new System.Drawing.Region();
inverted.MakeEmpty();
Rectangle rc = new Rectangle(0, 0, 0, 0);
bool inimage = false;
for (int y = 0; y < mask.Height; y++)
{
for (int x = 0; x < mask.Width; x++)
{
if (!inimage)
{
if (mask.GetPixel(x, y).ToArgb() != matchColor)
{
inimage = true;
rc.X = x;
rc.Y = y;
rc.Height = 1;
}
}
else
{
if (mask.GetPixel(x, y).ToArgb() == matchColor)
{
inimage = false;
rc.Width = x - rc.X;
inverted.Union(rc);
}
}
}
if (inimage)
{
inimage = false;
rc.Width = mask.Width - rc.X;
inverted.Union(rc);
}
}
return inverted;
}
来源:https://stackoverflow.com/questions/13039699/system-drawing-invert-region-build-out-of-path