c#多边形遮罩
本文关键字:多边形 | 更新日期: 2023-09-27 17:53:32
我有一个多边形的所有顶点的x, y坐标,比如(1,1)(20,10)(10,30),我如何生成一个多边形内部所有像素为1而外部为0的遮罩?我知道c#中有一个函数FillPolygon()
看起来几乎可以完成这项工作,但在我看来,它没有以任何方式返回掩码。
Bitmap b = new Bitmap(30, 30);
using (Graphics g = Graphics.FromImage(b))
{
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
g.Clear(Color.Black);
g.FillPolygon(Brushes.White, new Point[] {
new Point(5,5),
new Point(20,20),
new Point(2,15)});
}
byte[,] mask = new byte[b.Width, b.Height];
for (int y = 0; y < b.Height; y++)
for (int x = 0; x < b.Width; x++)
{
mask[x, y] = b.GetPixel(x, y).R > 0 ? 1 : 0;
}
如果您使用LockBits
而不是GetPixel
直接访问像素,这当然会更高效。
我知道这是一个相当老的问题,但万一有人来找类似的东西…
如果你只想获得掩码,有比引用System更好的方法。绘制和实际绘制到内存中的图像…
struct Point
{
public readonly int X;
public readonly int Y;
public Point(int x, int y)
{
this.X = x;
this.Y = y;
}
}
bool PointInPolygon(Point[] polygon, int x, int y)
{
if(polygon == null || polygon.Length < 3) return false;
int counter = 0;
double intersections;
Point p1 = polygon[0];
Point p2;
for (int i = 1; i <= polygon.Length; i++)
{
p2 = polygon[i % polygon.Length];
if ((y > (p1.Y < p2.Y ? p1.Y : p2.Y)) && (y <= (p1.Y > p2.Y ? p1.Y : p2.Y)) && (x <= (p1.X > p2.X ? p1.X : p2.X)) && (p1.Y != p2.Y))
{
intersections = (y - p1.Y) * (p2.X - p1.X) / (p2.Y - p1.Y) + p1.X;
if (p1.X == p2.X || x <= intersections) counter++;
}
p1 = p2;
}
return counter % 2 != 0;
}
void Main()
{
Point[] polygon = new Point[] { new Point(1,1), new Point(20,10), new Point(10,30) };
bool[,] mask = new bool[30,30];
for(int i=0;i<30;i++)
{
for(int j=0;j<30;j++)
{
mask[i,j] = PointInPolygon(polygon, i, j);
Console.Write(mask[i,j]?"*":".");
}
Console.WriteLine();
}
}
输出如下:
..............................
..............................
..............................
..***.........................
...*****......................
...********...................
....**********................
....**************............
.....****************.........
.....*******************......
......*********************...
......************************
.......*********************..
.......*******************....
........****************......
........**************........
.........***********..........
.........*********............
..........******..............
..........****................
..........**..................
..............................
..............................
..............................
..............................
..............................
..............................
..............................
..............................
..............................
对于遮罩,您可以使用区域