2012-04-06 57 views
2

使用颜色填充该区域内的点以填充该区域,类似于油漆桶功能中的“绘图”。
。 NET框架,没有直接的等价物。
但我希望使用C#来做到这一点。
有可能吗?如何使用颜色填充位图对象中的封闭区域

+0

这就是所谓的“颜色填充”。现在您可以搜索如何在C#中执行此操作。第一个结果可能是http://blog.csharphelper.com/2011/05/07/write-a-graphical-floodfill-method-in-c.aspx – Gabe 2012-04-06 13:18:45

+1

它就在那里,你需要使用GraphicsPath。注意它的FillMode属性。 – 2012-04-06 13:25:13

回答

2

这里是一个非常幼稚的洪水填充算法,应该让你开始

void Form1_Paint(object sender, PaintEventArgs e) 
{ 
    using (Bitmap bitmap = new Bitmap(500, 500)) 
    { 
     using (Graphics g = Graphics.FromImage(bitmap)) 
     { 
      g.Clear(Color.White); 
      List<Point> points = new List<Point>(); 
      for (double i = 0; i < 10; i++) 
      { 
       double dist = (i % 2 == 0) ? 100 : 50; 
       double x = 200 + Math.Cos(i/10d * Math.PI * 2d) * dist; 
       double y = 200 + Math.Sin(i/10d * Math.PI * 2d) * dist; 
       points.Add(new Point((int)x, (int)y)); 
      } 
      g.DrawPolygon(Pens.Black, points.ToArray()); 
     } 

     FloodFill(bitmap, 200, 200, Color.Red); 

     e.Graphics.DrawImage(bitmap, 0, 0); 
    } 
} 

void FloodFill(Bitmap bitmap, int x, int y, Color color) 
{ 
    BitmapData data = bitmap.LockBits(
     new Rectangle(0, 0, bitmap.Width, bitmap.Height), 
     ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); 
    int[] bits = new int[data.Stride/4 * data.Height]; 
    Marshal.Copy(data.Scan0, bits, 0, bits.Length); 

    LinkedList<Point> check = new LinkedList<Point>(); 
    int floodTo = color.ToArgb(); 
    int floodFrom = bits[x + y * data.Stride/4]; 
    bits[x + y * data.Stride/4] = floodTo; 

    if (floodFrom != floodTo) 
    { 
     check.AddLast(new Point(x, y)); 
     while (check.Count > 0) 
     { 
      Point cur = check.First.Value; 
      check.RemoveFirst(); 

      foreach (Point off in new Point[] { 
       new Point(0, -1), new Point(0, 1), 
       new Point(-1, 0), new Point(1, 0)}) 
      { 
       Point next = new Point(cur.X + off.X, cur.Y + off.Y); 
       if (next.X >= 0 && next.Y >= 0 && 
        next.X < data.Width && 
        next.Y < data.Height) 
       { 
        if (bits[next.X + next.Y * data.Stride/4] == floodFrom) 
        { 
         check.AddLast(next); 
         bits[next.X + next.Y * data.Stride/4] = floodTo; 
        } 
       } 
      } 
     } 
    } 

    Marshal.Copy(bits, 0, data.Scan0, bits.Length); 
    bitmap.UnlockBits(data); 
}